home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_xemacs.idb / usr / freeware / lib / xemacs-20.4 / lisp / auctex / bib-cite.el.z / bib-cite.el
Encoding:
Text File  |  1998-05-21  |  118.9 KB  |  2,718 lines

  1. ;; bib-cite.el - Display \cite, \ref or \label / Extract refs from BiBTeX file.
  2.  
  3. ;; Copyright (C) 1994, 1995, 1996, 1997 Peter S. Galbraith
  4.  
  5. ;; Author:    Peter S. Galbraith <galbraith@mixing.qc.dfo.ca>
  6. ;; Created:   06 July 1994
  7. ;; Version:   3.07 (20 Nov 97)
  8. ;; Keywords:  bibtex, cite, auctex, emacs, xemacs
  9.  
  10. ;; RCS $Id: bib-cite.el,v 1.24 1997/11/20 17:25:18 rhogee Exp $
  11. ;; Note: RCS version number does not correspond to release number.
  12.  
  13. ;; Everyone is granted permission to copy, modify and redistribute this
  14. ;; file provided:
  15. ;;   1. All copies contain this copyright notice.
  16. ;;   2. All modified copies shall carry a prominant notice stating who
  17. ;;      made modifications and the date of such modifications.
  18. ;;   3. The name of the modified file be changed.
  19. ;;   4. No charge is made for this software or works derived from it.
  20. ;;      This clause shall not be construed as constraining other software
  21. ;;      distributed on the same medium as this software, nor is a
  22. ;;      distribution fee considered a charge.
  23.  
  24. ;; LCD Archive Entry:
  25. ;; bib-cite|Peter Galbraith|galbraith@mixing.qc.dfo.ca|
  26. ;; Display \cite, \ref or \label / Extract refs from BiBTeX file.|
  27. ;; 21-May-1997|3.01|~/misc/bib-cite.el.gz|
  28.  
  29. ;; ----------------------------------------------------------------------------
  30. ;;; Commentary:
  31. ;; This minor-mode is used in various TeX modes to display or edit references
  32. ;; associated with \cite commands, or matching \ref and \label commands.
  33.  
  34. ;; New versions of this package (if they exist) may be found at:
  35. ;;   ftp://ftp.phys.ocean.dal.ca/users/rhogee/elisp/bib-cite.el
  36.  
  37. ;; Operating Systems:
  38. ;;  Works in unix, DOS and OS/2.  Developped under Linux.
  39. ;;  VMS: I have no clue if this works under VMS. I don't know how emacs handle 
  40. ;;  logical names (i.e. for BIBINPUTS) but I am willing to fix this package for
  41. ;;  VMS if someone if willing to test it and answer questions.
  42.  
  43. ;; AUC-TEX USERS: 
  44. ;;  auc-tex is a super-charged LaTeX mode for emacs. Get it at:
  45. ;;    ftp://ftp.iesd.auc.dk/pub/emacs-lisp/auctex.tar.gz       <-stable release
  46. ;;    ftp://ftp.dina.kvl.dk/pub/Staff/Per.Abrahamsen/auctex/   <-alpha release
  47. ;;
  48. ;;  WWW users may want to check out the AUC TeX page at
  49. ;;    http://www.iesd.auc.dk/~amanda/auctex/
  50. ;;
  51. ;;  bib-cite.el is included in the auc-tex distribution.  Therefore, if
  52. ;;  you use auc-tex, you probably have an old version of bib-cite.el in
  53. ;;  your load-path which may get loaded instead of this file (unless this
  54. ;;  is the auc-tex file!).  Make sure you replace that file, or rename it,
  55. ;;  or delete it!!!
  56.  
  57. ;; reftex users:
  58. ;;  reftex is a package with similar functions to bib-cite.
  59. ;;    ftp://strw.leidenuniv.nl/pub/dominik/reftex.el
  60. ;;  I suggest that you use reftex to help you type-in text as it's functions
  61. ;;  are better suited to this task than bib-cite, and use bib-cite's features
  62. ;;  when you proof-read the text.
  63. ;;  If you wish bib-cite to use reftex's reftex-view-crossref command to
  64. ;;  display and find \label's and \cite bibliography entries, set the variable
  65. ;;  bib-cite-use-reftex-view-crossref to t.
  66.  
  67. ;; MS-DOS USERS:
  68. ;;  Multifile documents are supported by bib-cite by using etags (TAGS files)
  69. ;;  which contains a bug for MSDOS (at least for emacs 19.27 it does).
  70. ;;  Get the file 
  71. ;;    ftp://ftp.phys.ocean.dal.ca/users/rhogee/elisp/bib-cite.etags-bug-report
  72. ;;  to see what patches to make to etags.c to fix it.
  73.  
  74. ;; Description:
  75. ;; ~~~~~~~~~~~
  76. ;; This package is used in various TeX modes to display or edit references
  77. ;; associated with \cite commands, or matching \ref and \label commands.
  78. ;; (so I actually overstep BiBTeX bounds here...)
  79. ;; These are the functions:
  80. ;;    
  81. ;;    bib-display bib-display-mouse
  82. ;;                           - Display citation, \ref or \label under point
  83. ;;    bib-find    bib-find-mouse
  84. ;;                           - Edit citation, \ref or \label under point
  85. ;;    bib-make-bibliography  - Make BiBTeX file containing only cite keys used.
  86. ;;    bib-apropos            - Search BiBTeX source files for keywords.
  87. ;;    bib-etags              - Refreshes (or builds) the TAGS files for 
  88. ;;                             multi-file documents.
  89. ;;    bib-create-auto-file   - Used in bibtex-mode to create cite key 
  90. ;;                             completion .el file for auctex.
  91. ;;    bib-highlight-mouse    - Highlight \cite, \ref and \label commands in 
  92. ;;                             green when the mouse is over them.
  93.  
  94. ;; About Cite Commands and related functions:
  95. ;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  96. ;;  Various flavors of \cite commands are allowed (as long as they contain
  97. ;;  the word `cite') and they may optionally have bracketed [] options.
  98. ;;  Bibtex Cross-references are displayed, and @string abbreviations are
  99. ;;  substituted or included.
  100. ;;
  101. ;;  The \cite text is found (by emacs) in the bibtex source files listed in the
  102. ;;  \bibliography command.  The BiBTeX files can be located in a search path
  103. ;;  defined by an environment variable (typically BIBINPUTS, but you can change
  104. ;;  this).
  105. ;;
  106. ;;  All citations used in a buffer can also be listed in a new bibtex buffer by
  107. ;;  using bib-make-bibliography.  This is useful to make a bibtex file for a
  108. ;;  document from a large bibtex database.  In this case, cross-references are
  109. ;;  included, as well as the @string commands used. The @string abbreviations
  110. ;;  are not substituted.
  111. ;;
  112. ;;  The bibtex files can also be searched for entries matching a regular
  113. ;;  expression using bib-apropos.
  114.  
  115. ;; Usage instructions:
  116. ;; ~~~~~~~~~~~~~~~~~~
  117. ;;  bib-display   Bound to Mouse-3 when specially highlighted. 
  118. ;;                In Hyperbole, bound to the Assist key.
  119. ;;                Bound to `\C-c b d'
  120. ;;
  121. ;;   bib-display will show the bibtex entry or the corresponding label or
  122. ;;   ref commands from anywhere within a document.
  123. ;;    With cursor on the \cite command itslef 
  124. ;;        -> display all citations of the cite command from the BiBTeX source.
  125. ;;    With cursor on a particular cite key within the brackets 
  126. ;;        -> display that citation's text from the BiBTeX source file(s).
  127. ;;
  128. ;;       Example:
  129. ;;
  130. ;;       \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
  131. ;;         ^Cursor -> Display-all-citations    ^Cursor -> Display-this-citation
  132. ;;
  133. ;;    With cursor on a \label command
  134. ;;        -> Display first matching \ref command in the document
  135. ;;    With cursor on a \ref command
  136. ;;        -> Display environment associated with the matching \label command.
  137. ;;
  138. ;;   Finding a ref or label within a multi-file document requires a TAGS file,
  139. ;;   which is automatically generated for you.  This enables you to then use
  140. ;;   any tags related emacs features.
  141. ;;
  142. ;;  bib-find      Bound to Mouse-2 when specially highlighted.  
  143. ;;                In Hyperbole, bound to the Action key.
  144. ;;                Bound to `\C-c b f'
  145. ;;
  146. ;;    bib-find will select the buffer and move point to the BiBTeX source file
  147. ;;    at the proper citation for a cite command, or move point to anywhere
  148. ;;    within a document for a label or ref command.  The ref chosen is the
  149. ;;    first occurrance within a document (using a TAGS file).  If point is
  150. ;;    moved within the same buffer, mark is set before the move and a message
  151. ;;    stating so is given.  If point is moved to another file, this is done in
  152. ;;    a new window using tag functions.  Within a plain file, the search
  153. ;;    pattern is set for another similar \ref command (since TAGS file are not
  154. ;;    used).  Within a multi-file document the following tag functions are
  155. ;;    appropriately setup:
  156. ;;
  157. ;;     C-u M-.     Find next alternate definition of last tag specified.
  158. ;;
  159. ;;     C-u - M-.   Go back to previous tag found.
  160. ;;
  161. ;;
  162. ;;    For multi-file documents, you must be using auctex (so that bib-cite can
  163. ;;    find the master file) and all \input and \include commands must be first
  164. ;;    on a line (not preceeded by any non-white text).
  165. ;;
  166. ;;  imenu support  (Suggested key binding: Shift-Mouse-3)  
  167. ;;
  168. ;;    If you want to bind imenu globally to Shift-Mouse-3, do so by adding the
  169. ;;    following to your ~/.emacs
  170. ;;
  171. ;;     (require 'imenu)
  172. ;;     (define-key global-map [S-mouse-3] 'imenu)
  173. ;;
  174. ;;    Another good place to define Imenu is in the menu-bar.  You can try this
  175. ;;    manually with
  176. ;;
  177. ;;     M-x imenu-add-to-menubar RET Imenu RET
  178. ;;
  179. ;;      or in a hook such as:
  180. ;;
  181. ;;    (add-hook 'LaTeX-mode-hook '(lambda () (imenu-add-to-menubar "Imenu"))) 
  182. ;; 
  183. ;;    The imenu facility (distributed with emacs) is supported by bib-cite to
  184. ;;    move point to a LaTeX section (or chapter) division or to a label
  185. ;;    declaration.  When editing a multi-file document, all such declarations
  186. ;;    within the document are displayed in the menu (again using a TAGS file).
  187. ;;    If you do not want to load imenu.el and use these features, set
  188. ;;    bib-use-imenu to nil. (This feature is disabled in xemacs because I'm
  189. ;;    told it doesn't have imenu).
  190. ;;
  191. ;;  bib-make-bibliography:     Bound to `\C-c b m'
  192. ;;
  193. ;;   Extract citations used in the current document from the \bibliography{}
  194. ;;   file(s).  Put them into a new suitably-named buffer.  In a auctex
  195. ;;   multi-file document, the .aux files are used to find the cite keys (for
  196. ;;   speed).  You will be warned if these are out of date.
  197. ;;
  198. ;;   This buffer is not saved to a file.  It is your job to save it to whatever
  199. ;;   name you wish.  Note that auctex has a unique name space for LaTeX and
  200. ;;   BiBTeX files, so you should *not* name the bib file associated with
  201. ;;   example.tex as example.bib!  Rather, name it something like
  202. ;;   example-bib.bib.
  203. ;;
  204. ;;  bib-apropos:               Bound to `\C-c b a'
  205. ;;
  206. ;;   Searches the \bibliography{} file(s) for entries containing a keyword and
  207. ;;   display them in the *help* buffer.  You can trim down your search by using
  208. ;;   bib-apropos in the *Help* buffer after the first invocation.  the current
  209. ;;   buffer is also searched for keyword matches if it is in bibtex-mode.
  210. ;;   
  211. ;;   It doesn't display cross-references nor does it substitute or display
  212. ;;   @string commands used.  It could easily be added, but it's faster this
  213. ;;   way.  Drop me a line if this would be a useful addition.
  214. ;;
  215. ;;   If you find yourself entering a cite command and have forgotten which key
  216. ;;   you want, but have entered a few initial characters as in `\cite{Gal',
  217. ;;   then invoke bib-apropos.  It will take that string (in this case `Gal') as
  218. ;;   an initial response to the apropos prompt.  You are free to edit it, or
  219. ;;   simply press carriage return.
  220. ;;
  221. ;;  bib-etags:                 Bound to `\C-c b e' 
  222. ;;
  223. ;;   Creates a TAGS file for auc-tex's multi-file document (or refreshes it).
  224. ;;   This is used by bib-find when editing multi-file documents.  The TAGS file
  225. ;;   is created automatically, but it isn't refreshed automatically.  So if
  226. ;;   bib-find can't find something, try running bib-etags again.  The *rescan*
  227. ;;   in imenu also calls bib-etags to refresh the TAGS file, so that is another
  228. ;;   way to generate it.
  229. ;;
  230. ;;  bib-create-auto-file:
  231. ;;
  232. ;;   Use this when editing a BiBTeX buffer to generate the auc-tex .el file
  233. ;;   which tell emacs about all its cite keys.  I've added this command to
  234. ;;   bibtex-mode pull-down menu.
  235. ;;
  236. ;;  bib-highlight-mouse:       Bound to `\C-c b h'
  237. ;;
  238. ;;   Highlights \cite, \ref and \label commands in green when the mouse is over
  239. ;;   them.  By default, a call to this function is added to LaTeX-mode-hook
  240. ;;   (via bib-cite-initialize) if you set bib-highlight-mouse-t to true.  But
  241. ;;   you may want to run this command to refresh the highlighting for newly
  242. ;;   edited text.
  243.  
  244. ;; Installation instructions:
  245. ;; ~~~~~~~~~~~~~~~~~~~~~~~~~
  246. ;;  bib-cite is a minor-mode, so you could invoke it in a LaTeX-mode hook.
  247. ;;  e.g. If you are using AUC-TeX (http://sunsite.auc.dk/auctex/), you could
  248. ;;  use:
  249. ;; 
  250. ;;   (autoload 'turn-on-bib-cite "bib-cite")
  251. ;;   (add-hook 'LaTeX-mode-hook 'turn-on-bib-cite)
  252. ;; 
  253. ;;  If you are using Emacs' regular LaTeX-mode, use instead:
  254. ;;
  255. ;;   (autoload 'turn-on-bib-cite "bib-cite")
  256. ;;   (add-hook 'latex-mode-hook 'turn-on-bib-cite)
  257. ;; 
  258. ;;  bib-cite can be used with auctex, or stand-alone.  If used with auctex on a
  259. ;;  multi-file document (and auctex's parsing is used), then all \bibliography
  260. ;;  commands in the document will be found and used.
  261. ;;  ---
  262. ;;  The following variable can be unset (like shown) to tell bib-cite to
  263. ;;  not give advice messages about which commands to use to find the next
  264. ;;  occurrence of a search: 
  265. ;;
  266. ;;    (setq bib-novice nil)
  267. ;;  ---
  268. ;;  If you wish bib-cite to use reftex's reftex-view-crossref command to
  269. ;;  display and find \label's and \cite bibliography entries, set the variable
  270. ;;  bib-cite-use-reftex-view-crossref to t:
  271. ;;
  272. ;;    (setq bib-cite-use-reftex-view-crossref t)
  273. ;;  ---
  274. ;;  The following variable determines whether we will attempt to highlight
  275. ;;  citation, ref and label commands in green when they are under the
  276. ;;  mouse.  When highlighted, the mouse keys work to call bib-display 
  277. ;;  (bound to [mouse-3]) and bib-find (bound to [mouse-2]).  If you use a 
  278. ;;  mode other than LaTeX-mode, you'll want to call bib-highlight-mouse with 
  279. ;;  a hook (See how we do this at the end of this file with the add-hook 
  280. ;;  command).
  281. ;;
  282. ;;    (setq bib-highlight-mouse-t nil)
  283. ;;  ---
  284. ;;  The imenu features will be disabled if you set this variable to nil
  285. ;;
  286. ;;    (setq bib-use-imenu nil)
  287. ;;
  288. ;;  This variable has no effect under XEmacs.
  289. ;;  ---
  290. ;;  If you use hilit19 (or hl319), then bib-display will use it to highlight 
  291. ;;  the display unless you turn this off with:
  292. ;;
  293. ;;    (setq bib-hilit-if-available nil)
  294. ;;
  295. ;;  If you don't use hilit19, or if this is nil, and if you use font-lock
  296. ;;  then it will be used by bib-display.
  297. ;;  ---
  298. ;;  The variable bib-switch-to-buffer-function sets the function used to 
  299. ;;  select buffers (if they differ from the original) in bib-cite commands
  300. ;;  bib-make-bibliography, bib-display, bib-find
  301. ;;  You may use `switch-to-buffer' `switch-to-buffer-other-window' or
  302. ;;  `switch-to-buffer-other-frame'.
  303. ;;  ---
  304. ;;  If you use DOS or OS/2, you may have to set the following variable:
  305. ;;
  306. ;;    (setq bib-dos-or-os2-variable t)
  307. ;;
  308. ;;    if bib-cite.el fails to determine that you are using DOS or OS/2.
  309. ;;  Try `C-h v bib-dos-or-os2-variable' to see if it needs to be set manually.
  310. ;;  ---
  311. ;;  bib-cite needs to call the etags program with its output file option
  312. ;;  and also with the append option (usually -a).
  313. ;;  I figured that DOS and OS/2 would use "etags /o=" instead of the unix
  314. ;;  variant "etags -o ", but users have reported differently.  So while the
  315. ;;  unix notation is used here, you can reset it if you need to like so:
  316. ;;
  317. ;;    (setq bib-etags-command        "etags /o=")
  318. ;;    (setq bib-etags-append-command "etags /a /o=")
  319. ;;  ---
  320. ;;  For multi-file documents, a TAGS file is generated by etags.  
  321. ;;  By default, its name is TAGS.  You can change this like so:
  322. ;;
  323. ;;    (setq bib-etags-filename "TAGSLaTeX")
  324. ;;  ---
  325. ;;  If your environment variable to find BiBTeX files is not BIBINPUTS, then
  326. ;;  reset it with the following variable (here, assuming it's TEXBIB instead):
  327. ;;
  328. ;;    (setq bib-bibtex-env-variable "TEXBIB")
  329. ;;
  330. ;;  Note that any directory ending in a double slash will cause bib-cite to
  331. ;;  search recursively through subdirectories for your .bib files.  This can
  332. ;;  be slow, so use this judiciously.
  333. ;;  e.g.  setenv BSTINPUTS .:/home/rhogee/LaTeX/bibinputs//
  334. ;;        -> all directories below /home/rhogee/LaTeX/bibinputs/ will be 
  335. ;;           searched.
  336. ;;  ---
  337. ;;  If you do not wish bib-display to substitute @string abbreviations, 
  338. ;;  then set the following variable like so:
  339. ;;
  340. ;;    (setq bib-substitute-string-in-display nil)
  341. ;;  ---
  342. ;;  Warnings are given when @string abbreviations are not defined in your bib
  343. ;;  files.  The exception is for months, usually defined in style files. If you
  344. ;;  use other definitions in styles file (e.g. journals), then you may add them
  345. ;;  to the `bib-substitute-string-in-display' list variable.
  346.  
  347. ;; If you find circumstances in which this package fails, please let me know.
  348.  
  349. ;; Things for me to do in later versions:
  350. ;; - jmv@di.uminho.pt (Jose Manuel Valenca) wants:
  351. ;; - prompt for \cite as well as \label and \ref 
  352. ;;   (and use auctex's completion list)
  353. ;; - implement string concatenation, with #[ \t\n]*STRING_NAME
  354. ;; - Create new command to substitute @string text in any bibtex buffer.
  355.  
  356. ;; ----------------------------------------------------------------------------
  357. ;;; Change log:
  358. ;; V3.07 Nov 20 97 - Christoph Wedler <wedler@fmi.uni-passau.de>  (RCS V1.24)
  359. ;;    bib-ext-list variable made permanent-local, otherwise VC registration 
  360. ;;    would use two extents for each reference etc. This was not a visible bug.
  361. ;; V3.06 Nov 12 97 - PSG (RCS V1.23)
  362. ;;    Support use of reftex's reftex-view-crossref command.
  363. ;; V3.05 Nov 12 97 - Vladimir Alexiev <vladimir@cs.ualberta.ca> (RCS V1.22)
  364. ;;    regexp-quote the bibliography keys so a key like galbraith+kelley97 works
  365. ;; V3.04 Aug 25 97 - Christoph Wedler  <wedler@fmi.uni-passau.de> (RCS V1.20)
  366. ;;    (bib-highlight-mouse): Would bug out on detached extents, 
  367. ;;    e.g. when killing a whole citation.
  368. ;; V3.03 Jul 16 97 - Christoph Wedler  <wedler@fmi.uni-passau.de> (RCS V1.18)
  369. ;;    turn-on-bib-cite back to non-interactive.
  370. ;; V3.02 Jul 11 97 - Christoph Wedler  <wedler@fmi.uni-passau.de> (RCS V1.17)
  371. ;;    * auctex/bib-cite.el (turn-on-bib-cite): Make interactive.
  372. ;;    Argument to `bib-cite-minor-mode' is 1.
  373. ;;    (bib-label-help-echo-format): New variable.
  374. ;;    (bib-label-help-echo): New function.
  375. ;;    (bib-label-help): Addition argument format.
  376. ;;    (bib-highlight-mouse): Set extent property `help-echo' for XEmacs.
  377. ;; V3.01 May 22 97 - Diego Calvanese <calvanes@dis.uniroma1.it> (RCS V1.16)
  378. ;;    bib-make-bibliography handles commas separated citations in aux files.
  379. ;; V3.00 May 16 97 - Peter Galbraith (RCS V1.15)
  380. ;;    bib-cite is now a minor mode.
  381. ;; V2.32 Apr 30 97 - Anders Stenman <stenman@isy.liu.se> (RCS V1.14)
  382. ;;  - Support for balloon-help.
  383. ;; V2.31 Mar 20 97 - Christoph Wedler <wedler@fmi.uni-passau.de> (RCS V1.12)
  384. ;;  - Better fontification of help buffer as bibtex or latex for XEmacs.
  385. ;; V2.30 Feb 10 97 - Peter Galbraith (RCS V1.11)
  386. ;;  - Better fontification of help buffer as bibtex or latex.
  387. ;; V2.29 Jan 29 97 - Peter Galbraith (RCS V1.10)
  388. ;;  - imenu looks for `\label{stuff}' instead of `\label'
  389. ;; V2.28 Jan 22 97 - Peter Galbraith (RCS V1.9)
  390. ;;  - Bug in bib-create-auto-file.
  391. ;; V2.27 Dec 31 96 - Peter Galbraith (RCS V1.8)
  392. ;;  - allow spaces between cite keys.
  393. ;;  - Vladimir Alexiev <vladimir@cs.ualberta.ca> 
  394. ;;     Allow () delimiters as well as {}.
  395. ;;     Better check on bibtex-menu
  396. ;;     Erase *bibtex-bibliography* buffer.
  397. ;; V2.26 Sep 24 96 - Peter Galbraith (RCS V1.7)
  398. ;;  imenu bug fix.
  399. ;; V2.25 Sep 23 96 - Anders Stenman <stenman@isy.liu.se> (RCS V1.6)
  400. ;;  XEmacs bib-cite-fontify-help-as-latex bug fix.
  401. ;; V2.24 Aug 19 96 - Peter Galbraith (RCS V1.3)
  402. ;;  XEmacs bug fix, minor defvars - Vladimir Alexiev <vladimir@cs.ualberta.ca>
  403. ;; V2.23 Aug 13 96 - Peter Galbraith (RCS V1.2)
  404. ;;   XEmacs - Add bib-cite entries to bibtex-mode popup menu.
  405. ;; V2.22 July 22 96 - Peter Galbraith (RCS V1.1)
  406. ;;   local-map has `m' for bib-make-bibliography instead of `b'
  407. ;;   set-buffer-menubar in XEmacs so that menu disappears after use.
  408. ;; V2.21 July 12 96 - Peter Galbraith
  409. ;;   Define `\C-c b' keymap for both plain tex and auctex, in XEmacs and emacs.
  410. ;;   Separate menu-bar menu in gnu emacs.
  411. ;;   font-lock support for bib-display'ed citations (bibtex fontification)
  412. ;;    and for matching \ref{} and \labels (latex fontification).
  413. ;;   buffer-substring-no-properties in bib-apropos 
  414. ;;    (bug in completing-read with mouse faces)
  415. ;;   imenu-sort-function made local and nil.
  416. ;;   imenu--LaTeX-name-and-position fixed for section name containing "\"
  417. ;;   Various other things... (whitespace within label strings, etc...)
  418. ;; V2.20 June 25 96 - Peter Galbraith
  419. ;;   imenu fixed for emacs-19.31.
  420. ;; V2.19 May 13 96
  421. ;;  PSG:
  422. ;;  - @string substitution fixed; bib-edit-citation fixed when buffer exists;
  423. ;;  Christoph Wedler <wedler@fmi.uni-passau.de>:
  424. ;;  - Added bib-switch-to-buffer-function 
  425. ;;  - (setq tags-always-exact nil) for xemacs
  426. ;;  - removed eval-after-load foe xemacs
  427. ;; V2.18 May 06 96 - PSG
  428. ;;   New eval-after-load from Fred Devernay <Frederic.Devernay@sophia.inria.fr>
  429. ;; V2.17 May 03 96 - PSG
  430. ;;   Fixed bug introduced in V2.16, reported by Dennis Dams <wsindd@win.tue.nl>
  431. ;; V2.16 May 02 96 - Vladimir Alexiev <vladimir@cs.ualberta.ca>
  432. ;; - somewhat compatible with Hyperbole by binding bib-find and bib-display to
  433. ;;   the Action and Assist keys inside the bib-highlight-mouse-keymap.
  434. ;; - makes more liberal provisions for users with a tty.
  435. ;; V2.15 Apr 09 96 - 
  436. ;; - fix "Buffer read-only" error caused by mouse-face text properties
  437. ;;   patch by Piet van Oostrum <piet@cs.ruu.nl>
  438. ;; - Use tmm non-X menu, patch by Vladimir Alexiev <vladimir@cs.ualberta.ca>
  439. ;; - input{file.txt} would not work. 
  440. ;;   bug report: David Kastrup <dak@pool.informatik.rwth-aachen.de>
  441. ;; V2.14 Feb 26 96 - PSG - define eval-after-load for xemacs 
  442. ;; Frederic Devernay's <Frederic.Devernay@sophia.inria.fr> suggestion.
  443. ;; V2.13 Feb 08 96 - Peter Galbraith - Fixed recursive use of bib-apropos.
  444. ;; V2.12 Jan 19 96 - Peter Galbraith 
  445. ;;   emacs-19.30's [down-mouse-1] is defined (rather than [mouse-1]), so
  446. ;;   bib-highlight-mouse-keymap now has [down-mouse-1] defined to override it.
  447. ;; V2.11  Nov 21 95 - Peter Galbraith 
  448. ;; - Fixed bib-create-auto-file when bib file loaded before LaTeX file.
  449. ;; - Michal Mnuk's better imenu labels menu <Michal.Mnuk@risc.uni-linz.ac.at>
  450. ;; - [mouse-1] and [mouse-2] key defs for highlighted regions.
  451. ;; - Improve X menus.
  452. ;; - Skip over style files in bib-document-TeX-files.
  453. ;; - Add menus and mouse highlighting for xemacs
  454. ;;   Anders Stenman <stenman@isy.liu.se> Dima Barsky <D.Barsky@ee.surrey.ac.uk>
  455. ;; - Check bib-use-imenu before calling LaTeX-hook-setq-imenu.
  456. ;;   From: Kurt Hornik <hornik@ci.tuwien.ac.at>
  457. ;; - Remove mouse face properties before inserting new ones.
  458. ;;   From: Peter Whaite <peta@Whippet.McRCIM.McGill.EDU>
  459. ;; V2.10  Aug 17 95 - Peter Galbraith - fatal bugs in bib-make-bibliography. 
  460. ;; V2.09  Jul 19 95 - Peter Galbraith 
  461. ;;   - Had introduced bug in search-directory-tree. synced with ff-paths.el.
  462. ;; V2.08  Jul 13 95 - Peter Galbraith
  463. ;;     Fred Douglis <douglis@research.att.com> says etags should be required
  464. ;; V2.07  Jul 04 95 - Peter Galbraith 
  465. ;;   - Minor changes with filename manipulations (careful with DOS...)
  466. ;;   - Problem if auc-tex not already loaded -> LaTeX-mode-map
  467. ;; V2.06  Jul 03 95 - Peter Galbraith - Added recursion through BIBINPUTS path.
  468. ;; V2.05  Jun 22 95 - Peter Galbraith  Bug: Hanno Wirth <wirth@jake.igd.fhg.de>
  469. ;;   bib-get-citations would truncate @String{KEY ="J. {\"u} Res."}
  470. ;; V2.04  Jun 19 95 - Peter Galbraith -
  471. ;;   - use bibtex-mode syntax table in bib buffer, else bib-apropos truncates
  472. ;;     an article if it contains an unbalanced closing parenthesis.
  473. ;;   - bib-highlight-mouse would mark a buffer modified
  474. ;; V2.03  May 16 95 - Peter Galbraith -
  475. ;;   auc-tec menu compatible with old "AUC TeX" pull-down name  
  476. ;; V2.02  May 10 95 - Peter Galbraith - 
  477. ;;   bug report by Bodo Huckestein <bh@thp.Uni-Koeln.DE> (getenv env) under DOS
  478. ;; V2.01  Mar 27 95 - Peter Galbraith - No imenu on xemacs; check BIBINPUT also
  479. ;; V2.00  Mar 27 95 - Peter Galbraith
  480. ;;   - bib-find and bib-display replace bib-edit-citation and 
  481. ;;      bib-display-citation
  482. ;;   - bib-apropos now take initial guess from start of cite argument at point.
  483. ;;   - Multi-file support for bib-make-bibliography using .aux files.
  484. ;;   - \label and \ref functionality for bib-find and bib-display:
  485. ;;     - \label may appear within an \begin\end or to label a (sub-)section.
  486. ;;     - Cursor on \label, goto first \ref, set next i-search to pattern.
  487. ;;     - Cursor on \ref, goto \label or display it's environment or section.
  488. ;;     - Works on hidden code!
  489. ;; V1.08  Jan 16 95 - Peter Galbraith
  490. ;;     bib-apropos can be used within *Help* buffer to trim a search.
  491. ;; V1.07  Dec 13 94 - Peter Galbraith
  492. ;;   - Fixed: multi-line @string commands in non-inserted display.
  493. ;;   - Fixed: quoted \ character in @string commands.
  494. ;;   - BiBTeX comments should not affect bib-cite
  495. ;;   - Fixed bib-apropos (from Christoph Wedler <wedler@fmi.uni-passau.de>)
  496. ;;      Faster now, and avoids infinite loops.
  497. ;;   - Added bib-edit-citation to edit a bibtex files about current citation.
  498. ;;   - Allow space and newlines between citations: \cite{ entry1, entry2}
  499. ;;   - Added bib-substitute-string-in-display,  bib-string-ignored-warning
  500. ;;     and bib-string-regexp.
  501. ;;   - bib-display-citation (from Markus Stricker <stricki@vision.ee.ethz.ch>)
  502. ;;      Could not find entry with trailing spaces
  503. ;; V1.06  Nov 20 94 - Peter Galbraith
  504. ;;   - Fixed bib-apropos for:
  505. ;;        hilighting without invoking bibtex mode. 
  506. ;;        display message when no matches found.
  507. ;;        would search only last bib file listed (forgot to `goto-char 1')
  508. ;;   - Fixed bib-make-bibliography that would only see first citation in a 
  509. ;;     multi-key \cite command (found by Michail Rozman <roz@physik.uni-ulm.de>
  510. ;;   - bib-make-bibliography didn't see \cite[A-Z]* commands.
  511. ;;     Found by Richard Stanton <stanton@haas.berkeley.edu>
  512. ;;     ************************************************** 
  513. ;;   - * Completely rewritten code to support crossrefs *
  514. ;;     **************************************************
  515. ;;   - autodetection of OS/2 and DOS for bib-dos-or-os2-variable
  516. ;;   - Created bib-display-citation-mouse
  517. ;;   - bib-apropos works in bibtex-mode on the current buffer
  518. ;;   - bibtex entry may have comma on next line (!)
  519. ;;       @ARTICLE{Kiryati-91
  520. ;;         , YEAR          = {1991    }
  521. ;;         ...
  522. ;; V1.05  Nov 02 94 - Peter Galbraith
  523. ;;   - bug fix by rossmann@TI.Uni-Trier.DE (Jan Rossmann) 
  524. ;;     for (boundp 'TeX-check-path) instead of fboundp.  Thanks!
  525. ;;   - Translate environment variable set by bib-bibtex-env-variable.
  526. ;;     (suggested by Richard Stanton <stanton@haas.berkeley.edu>)
  527. ;;   - add bib-dos-or-os2-variable to set environment variable path separator
  528. ;;   - Add key-defs for any tex-mode and auc-tex menu-bar entries. 
  529. ;;       [in auc-tec TeX-mode-map is common to both TeX and LaTeX at startup
  530. ;;        (but TeX-mode-map is only copied to LaTeX-mode-map at initilisation)
  531. ;;        in plain emacs, use tex-mode-map for both TeX and LaTeX.]
  532. ;;   - Add key def for bibtex-mode to create auc-tex's parsing file.
  533. ;;   - Fix bugs found by <thompson@loon.econ.wisc.edu>
  534. ;;     - fix bib-get-citation for options 
  535. ;;     - fix bib-get-citation for commas preceeded citation command
  536. ;;     - better regexp for citations and their keys.
  537. ;;     - Added @string support for any entry (not just journal entries).
  538. ;;       (I had to disallow numbers in @string keys because of years.  
  539. ;;        Is that ok?)
  540. ;;   - added bib-apropos
  541. ;; V1.04  Oct 24 94 - Peter Galbraith 
  542. ;;   - Don't require dired-aux, rather define the function we need from it.
  543. ;;   - Regexp-quote the re-search for keys.
  544. ;;   - Name the bib-make-bibliography buffer diffently than LaTeX buffer
  545. ;;     because auc-tex's parsing gets confused if same name base is used.
  546. ;; V1.03  Oct 24 94 - Peter Galbraith - require dired-aux for dired-split
  547. ;; V1.02  Oct 19 94 - Peter Galbraith
  548. ;;   - If using auc-tex with parsing activated, use auc-tex's functions
  549. ;;     to find all \bibliography files in a multi-file document.
  550. ;;   - Find bib files in pwd, BIBINPUTS environment variable path and
  551. ;;     TeX-check-path elisp variable path.
  552. ;;   - Have the parser ignore \bibliography that is on a commented `%' line.
  553. ;;     (patched by Karl Eichwalder <karl@pertron.central.de>)
  554. ;;   - Allow for spaces between entry type and key in bib files:
  555. ;;     (e.g  @Article{  key} )
  556. ;;     (suggested by Nathan E. Doss <doss@ERC.MsState.Edu>)
  557. ;;   - Allows options in \cite command (e.g. agu++ package \cite[e.g.][]{key})
  558. ;;   - Includes @String{} abbreviations for `journal' entries
  559. ;; V1.01 July 07 94 - Peter Galbraith - \bibliography command may have list of
  560. ;;                                      BibTeX files.  All must be readable.
  561. ;; V1.00 July 06 94 - Peter Galbraith - Created
  562. ;; ----------------------------------------------------------------------------
  563. ;;; Code:
  564.  
  565. ;;>>>>>>User-Modifiable variables start here:
  566.  
  567. (defvar bib-cite-use-reftex-view-crossref nil
  568.   "*Non-nil means, RefTeX will be used to find cross references.
  569. When this variable is non-nil, both `bib-find' and `bib-display' will
  570. call a function in RefTeX do find or display the cross reference of a
  571. \\ref or \\cite macro at point.")
  572.  
  573. (defvar bib-novice t
  574.   "*Give advice to novice users about what commands to use next.")
  575.  
  576. (defvar bib-use-imenu (not (string-match "XEmacs\\|Lucid" emacs-version))
  577.   "*Use imenu package for LaTeX modes (coded in bib-cite).")
  578.  
  579. (defvar bib-hilit-if-available t
  580.   "*Use hilit19 or hl319 to hilit bib-display if available")
  581.  
  582. (defvar bib-switch-to-buffer-function 'switch-to-buffer
  583.   "*Function used to select buffers if they differ from the original.
  584. You may use `switch-to-buffer' `switch-to-buffer-other-window' or
  585. `switch-to-buffer-other-frame'.")
  586.  
  587. (defvar bib-highlight-mouse-t t
  588.   "*Call bib-highlight-mouse from LaTeX-mode-hook to add green highlight.")
  589.  
  590. (defvar bib-label-help-echo-format "button2 finds %s, button3 displays %s"
  591.   "*Format string for info if the mouse is over LaTeX commands.
  592. If nil, do not display info.")
  593.  
  594. (defvar bib-bibtex-env-variable "BIBINPUTS"
  595.   "*Environment variable setting the path where BiBTeX input files are found.
  596. BiBTeX 0.99b manual says this should be TEXBIB.
  597. Another version says it should BSTINPUTS.  I don't know anymore!
  598.  
  599. The colon character (:) is the default path separator in unix, but you may
  600. use semi-colon (;) for DOS or OS/2 if you set bib-dos-or-os2-variable to `t'.")
  601.  
  602. (defvar bib-dos-or-os2-variable (or (equal 'emx system-type)
  603.                                     (equal 'ms-dos system-type))
  604. ;; Under OS/2 system-type equals emx
  605. ;; Under DOS  system-type equals ms-dos
  606.   "*`t' if you use DOS or OS/2 for bib-make-bibliography/bib-display
  607.  
  608. It tells bib-make-bibliography and bib-display to translate
  609. the BIBINPUTS environment variable using the \";\" character as
  610. a path separator and to translate DOS' backslash to slash.
  611.   
  612. e.g. Use a path like \"c:\\emtex\\bibinput;c:\\latex\\bibinput\"
  613.  
  614. (You can change the environment variable which is searched by setting the 
  615. elisp variable bib-bibtex-env-variable)")
  616.  
  617. (defvar bib-etags-command "etags -o "
  618.   "*Variable for the etags command and its output option.
  619. In unix, this is usually \"etags -o \"
  620. In DOS and OS/2, this *may* be \"etags /o=\"  If so, set it this variable.")
  621.  
  622. (defvar bib-etags-append-command "etags -a -o "
  623.   "*Variable for the etags command and its append and output option.
  624. In unix, this is usually \"etags -a -o \"
  625. In DOS and OS/2, this *may* be \"etags /a /o=\"  If so, set it this variable.")
  626.  
  627. (defvar bib-etags-filename "TAGS"
  628.    "*Variable for the filename generated by etags, by defaults this TAGS
  629. but you may want to change this to something like TAGSLaTeX such that it can
  630. coexist with some other tags file in your master file directory.")
  631.  
  632. (defvar bib-substitute-string-in-display t
  633.   "*Determines if bib-display will substitute @string definitions.
  634. If t, then the @string text is substituted.
  635. If nil, the text is not substituted but the @string entry is included.")
  636.  
  637. (defvar bib-string-ignored-warning 
  638.   '("jan" "feb" "mar" "apr" "may" "jun" "jul" "aug" "sep" "sept" "oct" "nov" 
  639.    "dec")
  640.   "*List of @string abbreviations for which a warning is given if not defined.
  641. These are usually month abbreviations (or journals) defined in a style file.")
  642.  
  643. ;;<<<<<<User-Modifiable variables end here.
  644.  
  645.  
  646. (defvar bib-cite-is-XEmacs
  647.   (not (null (save-match-data (string-match "XEmacs\\|Lucid" emacs-version)))))
  648.  
  649. (defvar bib-cite-minor-mode nil)
  650.  
  651. ;;;###autoload
  652. (defun bib-cite-minor-mode (arg)
  653.   "Toggle bib-cite mode.
  654. When bib-cite mode is enabled, citations, labels and refs are highlighted 
  655. when the mouse is over them.  Clicking on these highlights with [mouse-2] 
  656. runs bib-find, and [mouse-3] runs bib-display."
  657.   (interactive "P")
  658.   (set (make-local-variable 'bib-cite-minor-mode)
  659.        (if arg
  660.        (> (prefix-numeric-value arg) 0)
  661.      (not bib-cite-minor-mode)))
  662.   (cond 
  663.    (bib-cite-minor-mode                 ;Setup the minor-mode
  664.     ;; Christoph Wedler's <wedler@fmi.uni-passau.de> suggestion for xemacs
  665.     ;; Added for version 2.19
  666.     (if (boundp 'tags-always-exact)
  667.         (progn
  668.           (make-local-variable 'tags-always-exact)
  669.           (setq tags-always-exact nil)))
  670.     ;; imenu support
  671.     (if bib-use-imenu
  672.         (progn
  673.           ;; User who *never* uses multi-file documents could change this to:
  674.           ;;                              'imenu--create-LaTeX-index-for-buffer
  675.           (setq imenu-create-index-function 'imenu--create-LaTeX-index)
  676.           ;; Make sure that imenu-sort-function is nil
  677.           (and (boundp 'imenu-sort-function)
  678.                imenu-sort-function
  679.                (make-local-variable 'imenu-sort-function)
  680.                (setq imenu-sort-function nil))))
  681.     ;; mouse overlay        
  682.     (if bib-highlight-mouse-t
  683.         (progn
  684.           (bib-cite-setup-highlight-mouse-keymap)
  685.           (bib-highlight-mouse)
  686.           (make-local-hook 'after-change-functions)
  687.           (add-hook 'after-change-functions 
  688.                     'bib-cite-setup-mouse-function nil t)))
  689.     (if bib-cite-is-XEmacs
  690.     (progn
  691.       (or (local-variable-p 'current-menubar (current-buffer))
  692.           (set-buffer-menubar current-menubar))
  693.       (add-submenu nil bib-cite-minor-mode-menu))))
  694.    (t
  695.    ;;;Undo the minor-mode
  696.     ;; mouse overlay        
  697.     (cond 
  698.      (bib-cite-is-XEmacs
  699.       (while bib-ext-list
  700.         (delete-extent (car bib-ext-list))
  701.         (setq bib-ext-list (cdr bib-ext-list))))
  702.      (t
  703.       (remove-hook 'after-change-functions 'bib-cite-setup-mouse-function t)
  704.       (let ((before-change-functions) (after-change-functions))
  705.         ;; FIXME This detroys all mouse-faces and local-maps!
  706.         ;; FIXME Hope no other package is using them in this buffer!
  707.         (remove-text-properties (point-min) (point-max)
  708.                                 '(mouse-face t local-map t)))))
  709.     (if bib-cite-is-XEmacs
  710.         (delete-menu-item '("BCite"))))))
  711.  
  712. ;;This must be eval'ed when the LaTeX mode is in use.
  713. ;; bib-highlight-mouse-keymap is a local variable so each buffer can have it's
  714. ;; own.
  715. (defun bib-cite-setup-highlight-mouse-keymap ()
  716.   (make-local-variable 'bib-highlight-mouse-keymap)
  717.   (setq bib-highlight-mouse-keymap
  718.    ;;; First, copy the local keymap so we don't have `disappearing' menus
  719.    ;;; when the mouse is moved over a \ref, \label or \cite command.
  720.         
  721.    ;;; FIXME: Check out (mouse-major-mode-menu) to see how it grabs the local
  722.    ;;;        menus to display.  Maybe on `highlighted' commands we could only
  723.    ;;;        display the bib-cite stuff (or a subset of it).
  724.         (let ((m (copy-keymap (current-local-map))))
  725.           (cond
  726.            (bib-cite-is-XEmacs
  727.             (set-keymap-name m 'bib-highlight-mouse-keymap)
  728.             (cond
  729.              ;;action-key stuff from Vladimir Alexiev <vladimir@cs.ualberta.ca>
  730.              ((commandp 'action-key)
  731.               ;; for hyperbole. The Right Way is to define implicit buttons
  732.               ;; (defib) bib-cite and label-ref instead of overriding
  733.               ;; action-key and assist key, so that eg smart key help can
  734.               ;; be obtained, but I'm lazy.
  735.               (substitute-key-definition 'action-key 'bib-find m global-map)
  736.               (substitute-key-definition 'assist-key 'bib-display m global-map)
  737.               (substitute-key-definition 'action-key-depress 
  738.                                          'bib-find-mouse m global-map)
  739.               (substitute-key-definition 'assist-key-depress 
  740.                                          'bib-display-mouse m global-map)
  741.               (substitute-key-definition 'action-mouse-key nil m global-map)
  742.               (substitute-key-definition 'assist-mouse-key nil m global-map))
  743.              (t                               ; xemacs, not hyperbole
  744.               (define-key m "\e\r" 'bib-find-mouse) ;   bug Fixed in V2.17
  745.               (define-key m "\e\n" 'bib-display-mouse) ;bug Fixed in V2.17
  746.               ;;(define-key m [(shift button1)] 'bib-display-mouse)
  747.               (define-key m [button3] 'bib-display-mouse)
  748.               (define-key m [button2] 'bib-find-mouse))))
  749.             (t                                 ; emacs 19
  750.              (cond
  751.               ((commandp 'action-key)
  752.                (substitute-key-definition 'action-key 'bib-find m global-map)
  753.                (substitute-key-definition 'assist-key 'bib-display m global-map)
  754.                (substitute-key-definition 'action-mouse-key-emacs19 
  755.                                           'bib-find-mouse m global-map)
  756.                (substitute-key-definition 'assist-mouse-key-emacs19 
  757.                                           'bib-display-mouse m global-map)
  758.                (substitute-key-definition 'action-key-depress-emacs19 
  759.                                           nil m global-map)
  760.                (substitute-key-definition 'assist-key-depress-emacs19 
  761.                                           nil m global-map))
  762.               (t                               ; emacs 19, not hyperbole
  763.                (define-key m [down-mouse-3] 'bib-display-mouse)
  764.                (define-key m [mouse-2] 'bib-find-mouse)))))
  765.           m)))
  766.  
  767. ;;;###autoload
  768. (defun turn-on-bib-cite ()
  769.   "Unconditionally turn on Bib Cite mode."
  770.   (bib-cite-minor-mode 1))
  771.  
  772. (defun bib-cite-setup-mouse-function (beg end old-len)
  773.   (save-excursion
  774.     (save-match-data
  775.       (save-restriction
  776.         (narrow-to-region
  777.          (progn (goto-char beg) (beginning-of-line) (point))
  778.          (progn (goto-char end) (forward-line 1) (point)))
  779.         (bib-highlight-mouse)))))
  780.  
  781. (defvar bib-cite-minor-mode-map
  782.   (let ((map (make-sparse-keymap)))
  783.     (define-key map "\C-cba" 'bib-apropos)
  784.     (define-key map "\C-cbb" 'bib-make-bibliography)
  785.     (define-key map "\C-cbd" 'bib-display)
  786.     (define-key map "\C-cbe" 'bib-etags)
  787.     (define-key map "\C-cbf" 'bib-find)
  788.     (define-key map "\C-cbh" 'bib-highlight-mouse)
  789.     map)
  790.   "bib-cite minor-mode keymap")
  791.  
  792. (easy-menu-define 
  793.  bib-cite-minor-mode-menu bib-cite-minor-mode-map "Menu keymap for bib-cite."
  794.  '("BCite"
  795.    ["Make BibTeX bibliography buffer" bib-make-bibliography t]
  796.    ["Display citation or matching \\ref or \\label" bib-display t]
  797.    ["Find BibTeX citation or matching \\ref or \\label" bib-find t]
  798.    ["Search apropos BibTeX files" bib-apropos t]
  799.    ["Build TAGS file for multi-file document" bib-etags (bib-master-file)]
  800.    ["Refresh \\cite, \\ref and \\label mouse highlight"
  801.     bib-highlight-mouse t]))
  802.  
  803. ;; Install ourselves:
  804. (or (assq 'bib-cite-minor-mode minor-mode-alist)
  805.     (setq minor-mode-alist 
  806.           (cons '(bib-cite-minor-mode " BCite") minor-mode-alist)))
  807. (or (assq 'bib-cite-minor-mode minor-mode-map-alist)
  808.     (setq minor-mode-map-alist 
  809.           (cons (cons 'bib-cite-minor-mode bib-cite-minor-mode-map) 
  810.                 minor-mode-map-alist)))
  811.   
  812.  
  813. ;;; Add a menu entry to bibtex.el (Perhaps I should not do this).
  814. (cond
  815.  ((and (string-match "XEmacs\\|Lucid" emacs-version)
  816.        (or window-system
  817.            (fboundp 'smart-menu)))      ;text menus by Bob Weiner
  818.   ;;
  819.   ;; xemacs under X with auc-tex
  820.   ;;
  821.  
  822.   ;; Add to bibtex.el's popup menu
  823.   (defvar bib-cite-xemacs-bibtex-mode-menu
  824.     '("---"
  825.       "Bib-Cite"
  826.       "---"
  827.       ["Search apropos BibTeX files" bib-apropos t]
  828.       ["Create auc-tex auto parsing file" bib-create-auto-file t])
  829.     "Submenu of bibtex-mode menu, used by bib-cite.")
  830.   
  831.   (if (boundp 'bibtex-menu)
  832.       ;; Add menu now
  833.       (setq bibtex-menu
  834.         (append
  835.          bibtex-menu
  836.          bib-cite-xemacs-bibtex-mode-menu))
  837.     ;; Setup to add menu later
  838.     (defun bib-cite-bibtex-mode-hook ()
  839.       (if (boundp 'bibtex-menu)
  840.           (progn
  841.             (setq bibtex-menu
  842.                   (append
  843.                    bibtex-menu
  844.                    bib-cite-xemacs-bibtex-mode-menu))
  845.             (remove-hook 'bibtex-mode-hook 'bib-cite-bibtex-mode-hook))))
  846.     (add-hook 'bibtex-mode-hook 'bib-cite-bibtex-mode-hook))
  847.   )
  848.  
  849.  ((and (not (string-match "XEmacs\\|Lucid" emacs-version))
  850.        (string-equal "19" (substring emacs-version 0 2))
  851.        (or window-system
  852.            (fboundp 'tmm-menubar)))     ; 19.30 - Will autoload if necessary 
  853.   ;;
  854.   ;; emacs-19 under X-windows (or non-X with tmm)
  855.   ;;
  856.   
  857.   ;; This *almost* makes me want to switch over to XEmacs...
  858.  
  859.   ;; to auc-tex auto file for a bibtex buffer
  860.   (eval-after-load 
  861.    "bibtex"
  862.    '(progn
  863.       (cond
  864.        ((lookup-key bibtex-mode-map [menu-bar move/edit])
  865.         (define-key-after 
  866.           (lookup-key bibtex-mode-map [menu-bar move/edit]) 
  867.           [bib-nil] '("---" . nil) '"--")
  868.         (define-key-after 
  869.           (lookup-key bibtex-mode-map [menu-bar move/edit]) 
  870.           [bib-apropos] '("Search Apropos" . bib-apropos) 'bib-nil)
  871.         (define-key-after 
  872.           (lookup-key bibtex-mode-map [menu-bar move/edit]) 
  873.           [auc-tex-parse] 
  874.           '("Create auc-tex auto parsing file" . bib-create-auto-file)
  875.           'bib-apropos))
  876.        ((lookup-key bibtex-mode-map [menu-bar bibtex-edit])
  877.         (define-key-after 
  878.           (lookup-key bibtex-mode-map [menu-bar bibtex-edit]) 
  879.           [bib-nil] '("---" . nil) '"--")
  880.         (define-key-after 
  881.           (lookup-key bibtex-mode-map [menu-bar bibtex-edit]) 
  882.           [bib-apropos] '("Search Apropos" . bib-apropos) 'bib-nil)
  883.         (define-key-after 
  884.           (lookup-key bibtex-mode-map [menu-bar bibtex-edit]) 
  885.           [auc-tex-parse] 
  886.           '("Create auc-tex auto parsing file" . bib-create-auto-file)
  887.           'bib-apropos)))))))
  888.  
  889. ;; Following from bibtex.el
  890. (defvar 
  891.   bib-cite-bibtex-font-lock-keywords
  892.   '(("^\\( \\|\t\\)*\\(@[A-Za-z]+\\)[ \t]*[({]\\([][A-Za-z0-9.:;?!`'()/*@_+=|<>-]+\\)?"
  893.      (2 font-lock-function-name-face)
  894.      (3 font-lock-reference-face nil t))
  895.     ;; reference type and reference label
  896.     ("^[ \t]*\\(OPT[^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*\\)[ \t]*="
  897.      1 font-lock-comment-face)
  898.     ;; optional field names (treated as comments)
  899.     ("^[ \t]*\\([^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*\\)[ \t]*="
  900.      1 font-lock-variable-name-face)
  901.     ;; field names
  902.     "Default expressions to fontify in BibTeX mode."))
  903.  
  904. (defvar bib-cite-bibtex-mode-syntax-table
  905.   (let ((st (make-syntax-table)))
  906.     ;; [alarson:19920214.1004CST] make double quote a string quote
  907.     (modify-syntax-entry ?\" "\"" st)
  908.     (modify-syntax-entry ?$ "$$  " st)
  909.     (modify-syntax-entry ?% "<   " st)
  910.     (modify-syntax-entry ?'  "w   " st)
  911.     (modify-syntax-entry ?@  "w   " st)
  912.     (modify-syntax-entry ?\\ "\\" st)
  913.     (modify-syntax-entry ?\f ">   " st)
  914.     (modify-syntax-entry ?\n ">   " st)
  915.     (modify-syntax-entry ?~ " " st)
  916.     st))
  917. ;; Code from bibtex.el ends
  918.  
  919. ;; @string starts with a letter and does not contain any of ""#%'(),={}
  920. ;; Here we do not check that the field contains only one string field and
  921. ;; nothing else.
  922. (defvar bib-string-regexp
  923.       "^[, \t]*[a-zA-Z]+[ \t]*=[ \t]*\\([a-zA-Z][^#%'(),={}\" \t\n]*\\)"
  924.       "Regular expression for field containing a @string")
  925.  
  926. (defvar bib-ext-list nil 
  927.   "xemacs buffer-local list of bib-cite extents.")
  928. (make-variable-buffer-local 'bib-ext-list)
  929. (put 'bib-ext-list 'permanent-local t)
  930.  
  931. (defun bib-display ()
  932.   "Display BibTeX citation or matching \\ref or \\label command under point.
  933.  
  934. If text under cursor is a \\cite command, then display its BibTeX info from
  935. \\bibliography input file.
  936.    Example with cursor located over cite command or arguments:
  937.      \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
  938.         ^Display-all-citations          ^Display-this-citation
  939.  
  940. If text under cursor is a \\ref command, then display environment associated 
  941. with its matching \\label command. 
  942.  
  943. If text under cursor is a \\label command, then display the text around
  944. the first matching \\ref command.
  945.  
  946. The user is prompted for a \\label or \\ref is nothing suitable is found under
  947. the cursor.  The first prompt is for a label. If you answer with an empty 
  948. string, a second prompt for a ref will be given.
  949.  
  950. A TAGS file is created and used for multi-file documents under auctex."
  951.   (interactive)
  952.   (let ((cite)(ref)(label))
  953.     (save-excursion
  954.       (if (not (looking-at "\\\\"))
  955.           (search-backward "\\" nil t))
  956.       (if (looking-at "\\\\ref{") 
  957.           (setq ref t)
  958.         (if (looking-at "\\\\label{")
  959.             (setq label t)              
  960.           (setq cite t))))
  961.     (cond 
  962.      ;; reftex doesn't handle label->ref
  963.      ((and bib-cite-use-reftex-view-crossref
  964.            (or ref cite))
  965.       ;;;FIXME: reftex doesn't want point on \ref or \cite part, but on keyword
  966.       (require 'reftex)
  967.       (reftex-view-crossref nil))
  968.      (cite
  969.       (bib-display-citation))
  970.      (t
  971.       (bib-display-label)))))
  972.  
  973. (defun bib-find ()
  974.   "Edit BibTeX citation or find matching \\ref or \\label command under point.
  975.  
  976. For multi-entry cite commands, the cursor should be on the actual cite key
  977. desired (otherwise a random entry will be selected).
  978. e.g.: \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
  979.                         ^Display-this-citation
  980.  
  981. If text under cursor is a \\ref command, then point is moved to its matching 
  982. \\label command. 
  983.  
  984. If text under cursor is a \\label command, then point is moved to the first 
  985. matching \\ref command.
  986.  
  987. The user is prompted for a \\label or \\ref is nothing suitable is found under
  988. the cursor.  The first prompt is for a label. If you answer with an empty 
  989. string, a second prompt for a ref will be given.
  990.  
  991. A TAGS file is created and used for multi-file documents under auctex."
  992.   (interactive)
  993.   (let ((cite)(ref)(label))
  994.     (save-excursion
  995.       (if (not (looking-at "\\\\"))
  996.           (search-backward "\\" nil t))
  997.       (if (looking-at "\\\\ref{") 
  998.           (setq ref t)
  999.         (if (looking-at "\\\\label{")
  1000.             (setq label t)              
  1001.           (setq cite t))))
  1002.     (cond 
  1003.      ;; reftex doesn't handle label->ref
  1004.      ((and bib-cite-use-reftex-view-crossref
  1005.            (or ref cite))
  1006.       (require 'reftex)
  1007.       (reftex-view-crossref t))
  1008.      (cite
  1009.       (bib-edit-citation))
  1010.      (t
  1011.       (bib-find-label)))))
  1012.  
  1013. (defun bib-display-mouse (EVENT)
  1014.   "Display BibTeX citation or matching \\ref or \\label command under mouse.
  1015. See bib-display."
  1016.   (interactive "e")
  1017.   (mouse-set-point EVENT)
  1018.   (bib-display))
  1019.  
  1020. (defun bib-find-mouse (EVENT)
  1021.   "Edit BibTeX citation or find matching \\ref or \\label command under mouse.
  1022. See bib-find."
  1023.   (interactive "e")
  1024.   (mouse-set-point EVENT)
  1025.   (bib-find))
  1026.  
  1027. (defun bib-apropos ()
  1028.   "Display BibTeX entries containing a keyword from bibliography file.
  1029. The files specified in the \\bibliography command are searched unless
  1030. the current buffer is in bibtex-mode or is the Help buffer.  In those
  1031. cases, *it* is searched.  This allows you to trim down a search further 
  1032. by using bib-apropos sequentially."
  1033.   ;;(interactive "sBibTeX apropos: ")
  1034.   (interactive)
  1035.   (let* ((keylist (and (boundp 'TeX-auto-update) ;Avoid error in FRAMEPOP
  1036.                        (fboundp 'LaTeX-bibitem-list) ;Use this if using auctex
  1037.                        (LaTeX-bibitem-list)))
  1038.          (keyword (bib-apropos-keyword-at-point))
  1039.          (keyword (completing-read "BiBTeX apropos: " keylist nil nil keyword))
  1040.          (the-text)(key-point)(start-point)
  1041.          (new-buffer-f (and (not (string-match "^bib" mode-name))
  1042.                             (not (string-equal "*Help*" (buffer-name)))))
  1043.          (bib-buffer (or (and new-buffer-f (bib-get-bibliography nil))
  1044.                          (current-buffer))))
  1045.     (save-excursion
  1046.       (set-buffer bib-buffer)
  1047.       (goto-char (point-min))
  1048.       (while (and (re-search-forward "^[ \t]*@" nil t)
  1049.                   (re-search-forward keyword nil t))
  1050.         (setq key-point (point))        ;To make sure this is within entry
  1051.         (re-search-backward "^[ \t]*@" nil t)
  1052.         (setq start-point (point))
  1053.         (forward-list 1)
  1054.         (if (< (point) key-point)       ;And this is that test...
  1055.             (goto-char key-point)       ;Not within entry, skip it.
  1056.           (setq the-text 
  1057.                 (cons (concat (buffer-substring start-point (point)) "\n")
  1058.                       the-text))))
  1059.       (if (not the-text)
  1060.           (message "Sorry, no matches found.")
  1061.         (with-output-to-temp-buffer "*Help*" 
  1062.           (mapcar 'princ (nreverse the-text)))
  1063.         (bib-cite-fontify-help-as-bibtex)
  1064.         (if bib-novice
  1065.             (message
  1066.              (substitute-command-keys
  1067.               (concat "Use \\[bib-apropos] again in the *help* buffer"
  1068.                       " to trim the search")))))
  1069.       (if new-buffer-f
  1070.           (kill-buffer bib-buffer)))))
  1071.  
  1072. (defvar bib-document-citekeys-obarray-warnings nil
  1073.   "bib-cite internal variable")
  1074.  
  1075. (defun bib-make-bibliography ()
  1076.   "Extract citations used in the current document from \bibliography{} file(s).
  1077. Put them into a buffer named after the current buffer, with extension .bib.
  1078.  
  1079. In an auc-tex multi-file document, parsing must be on and the citation keys
  1080. are extracted from the .aux files.
  1081.  
  1082. In a plain LaTeX buffer (not multi-file), the cite keys are extracted from 
  1083. the text itself.  Therefore the text need not have been previously processed
  1084. by LaTeX.  
  1085.  
  1086. This function is useful when you want to share a LaTeX file, and therefore want
  1087. to create a bibtex file containing only the references used in the document."
  1088.   (interactive)
  1089.   (let* ((the-keys-obarray (or (bib-document-citekeys-obarray)
  1090.                                (bib-buffer-citekeys-obarray)))
  1091.                                         ;1st in case of error
  1092.          (new-buffer 
  1093.           (create-file-buffer 
  1094.            (concat (substring (buffer-name) 0 
  1095.                               (or (string-match "\\." (buffer-name))
  1096.                                   (length (buffer-name))))
  1097.                    "-bib.bib")))
  1098.          (bib-buffer (bib-get-bibliography nil))
  1099.          (the-warnings (bib-get-citations the-keys-obarray
  1100.                                           bib-buffer
  1101.                                           new-buffer
  1102.                                           nil)))
  1103.     (kill-buffer bib-buffer)
  1104. ;;; (switch-to-buffer new-buffer)
  1105.     (funcall bib-switch-to-buffer-function new-buffer)
  1106.     (bibtex-mode)
  1107.     (cond
  1108.      ((and bib-hilit-if-available
  1109.            (fboundp 'hilit-highlight-region))
  1110.       (hilit-highlight-buffer t))
  1111.      ((featurep 'font-lock)             ;Perhaps let the user's setup determine
  1112.       (font-lock-fontify-buffer)))      ; if font-lock fontifies?
  1113.     (if (or bib-document-citekeys-obarray-warnings
  1114.             the-warnings)
  1115.         (progn
  1116.           (cond
  1117.            ((and bib-document-citekeys-obarray-warnings the-warnings)
  1118.             (with-output-to-temp-buffer "*Help*" 
  1119.               (princ bib-document-citekeys-obarray-warnings the-warnings)))
  1120.            (bib-document-citekeys-obarray-warnings
  1121.             (with-output-to-temp-buffer "*Help*" 
  1122.               (princ bib-document-citekeys-obarray-warnings)))
  1123.            (the-warnings
  1124.             (with-output-to-temp-buffer "*Help*" (princ the-warnings))))
  1125.           (setq bib-document-citekeys-obarray-warnings nil) ;Reset
  1126.           (bib-cite-fontify-red)))
  1127.     (if bib-novice
  1128.         (message
  1129.          (substitute-command-keys
  1130.           "Use \\[save-buffer] to save this buffer to a file.")))))
  1131.  
  1132. (defun bib-cite-fontify-red (&optional limit)
  1133.   "Fontify *Help* buffer in red-bold up to optional limit"
  1134.   (if (and window-system                ;Not exactly correct for XEmacs
  1135.            (not (facep 'red-bold)))
  1136.       (progn
  1137.         (copy-face 'bold 'red-bold)
  1138.         (set-face-foreground 'red-bold "red")))
  1139.   (save-excursion
  1140.     (set-buffer "*Help*")
  1141.     (let ((before-change-functions) (after-change-functions))
  1142.       (put-text-property (point-min)(or limit (point-max)) 
  1143.                          'face 'red-bold))))
  1144.  
  1145. (defun bib-cite-fontify-help-xemacs (defaults)
  1146.   (if (fboundp 'font-lock-set-defaults-1) ; >= XEmcas 19.14
  1147.       (progn
  1148.     (set-buffer "*Help*")
  1149.     (setq font-lock-defaults-computed nil
  1150.           font-lock-keywords nil)
  1151.     (font-lock-set-defaults-1
  1152.      (and defaults (font-lock-find-font-lock-defaults defaults)))
  1153.     (font-lock-fontify-buffer)
  1154.     (setq font-lock-defaults-computed nil
  1155.           font-lock-keywords nil)
  1156.     (font-lock-set-defaults-1))))
  1157.     
  1158. (defun bib-cite-fontify-help-as-bibtex ()
  1159.   (save-excursion
  1160.     (cond 
  1161.      ((and bib-hilit-if-available
  1162.            (fboundp 'hilit-highlight-region))
  1163.       (set-buffer "*Help*")
  1164.       (hilit-highlight-region (point-min) (point-max) 'bibtex-mode t))
  1165.      ((not (featurep 'font-lock))
  1166.       nil)                              ;No font-lock! Stop here.
  1167.      ;; font-lock under Emacs and XEmacs
  1168.      ((string-match "XEmacs\\|Lucid" emacs-version)
  1169.       ;; XEmacs
  1170.       (bib-cite-fontify-help-xemacs 'bibtex-mode))
  1171.      (t
  1172.       ;; Emacs
  1173.       (set-buffer "*Help*")
  1174.       (let ((font-lock-defaults 
  1175.              '(bib-cite-bibtex-font-lock-keywords
  1176.                nil t ((?$ . "\"")(?\" . ".")))))
  1177.         (if font-lock-mode
  1178.             (font-lock-mode)
  1179.           (font-lock-unset-defaults)
  1180.           (font-lock-unfontify-buffer))
  1181.         (font-lock-fontify-buffer))))))
  1182.  
  1183. (defun bib-cite-fontify-help-as-latex ()
  1184.   (save-excursion
  1185.     (cond 
  1186.      ((and bib-hilit-if-available
  1187.            (fboundp 'hilit-highlight-region))
  1188.       (set-buffer "*Help*")
  1189.       (hilit-highlight-region (point-min) (point-max) 'latex-mode t))
  1190.      ((not (featurep 'font-lock))
  1191.       nil)                              ;No font-lock! Stop here.
  1192.      ;; font-lock under Emacs and XEmacs
  1193.      ((string-match "XEmacs\\|Lucid" emacs-version)
  1194.       ;; XEmacs, not necessary to do s.th. special for font-latex, we do *not*
  1195.       ;; want the buffer-local faces!
  1196.       (bib-cite-fontify-help-xemacs 'latex-mode))
  1197.      (t
  1198.       ;; Emacs
  1199.       (set-buffer "*Help*")
  1200.       ;; Actually, don't want to `permanently' affect *Help* buffer...
  1201.       ;;(if (featurep 'font-latex)
  1202.       ;; (font-latex-setup)
  1203.       ;; Rather I should deal with this in the `let' form:
  1204.       ;; (make-local-variable 'font-lock-string-face)
  1205.       ;; (setq font-lock-string-face font-latex-math-face
  1206.       ;;       font-latex-string-face (default-value 'font-lock-string-face))
  1207.       (let ((font-lock-defaults 
  1208.              (if (featurep 'font-latex)
  1209.                  '((font-latex-keywords font-latex-keywords-1 
  1210.                                         font-latex-keywords-2)
  1211.                    nil nil ((?\( . ".") (?\) . ".") (?$ . "\"")) nil
  1212.                    (font-lock-comment-start-regexp . "%")
  1213.                    (font-lock-mark-block-function . mark-paragraph))
  1214.                '(tex-font-lock-keywords nil nil ((?$ . "\""))))))
  1215.         (if font-lock-mode
  1216.             (font-lock-mode)
  1217.           (font-lock-unset-defaults)
  1218.           (font-lock-unfontify-buffer))
  1219.         (font-lock-fontify-buffer))))))
  1220.  
  1221. (defvar bib-document-TeX-files-warnings nil 
  1222.   "bib-cite internal variable")
  1223.  
  1224. (defun bib-etags (&optional masterdir)
  1225.   "Invoke etags on all tex files of the document, storing the TAGS file
  1226. in the master-directory.  Expect errors if you use this outside of auctex
  1227. or within a plain single-file document.
  1228. Also makes sure that the TAGS buffer is updated.
  1229. See variables bib-etags-command and bib-etags-filename"
  1230.   (interactive)
  1231.   (require 'etags)
  1232.   (let* ((the-file-list (bib-document-TeX-files))
  1233.          (the-file (car the-file-list))
  1234.          (dir (or masterdir (bib-master-directory)))
  1235.          (the-tags-file (expand-file-name bib-etags-filename dir))
  1236.          (the-tags-buffer (get-file-buffer the-tags-file)))
  1237.     ;; Create TAGS file with first TeX file (master file)
  1238.     (shell-command (concat bib-etags-command the-tags-file " " the-file))
  1239.     (setq the-file-list (cdr the-file-list))
  1240.     ;; Append to TAGS file for all other TeX files.
  1241.     (while the-file-list
  1242.       (setq the-file (car the-file-list)) 
  1243.       (shell-command 
  1244.        (concat bib-etags-append-command the-tags-file " " the-file))
  1245.       (setq the-file-list (cdr the-file-list)))
  1246.     (if the-tags-buffer                 ;buffer existed; we must refresh it.
  1247.         (save-excursion
  1248.           (set-buffer the-tags-buffer)
  1249.           (revert-buffer t t)))
  1250.  
  1251.     ;; Check value of tags-file-name against the-tags-file
  1252.     (or (equal the-tags-file  tags-file-name) ;make sure it's current
  1253.         (visit-tags-table the-tags-file)) 
  1254.  
  1255.     ;(set (make-local-variable 'tags-file-name) the-tags-file))
  1256.     ;; above should not be needed
  1257.  
  1258.     ;; Weird Bug:
  1259.     ;;  (visit-tags-table-buffer) seems to get called twice when called by 
  1260.     ;;  find-tag on an undefined tag. The second time, it's in the TAGS 
  1261.     ;;  buffer and returns an error because TAGS buffer does have 
  1262.     ;;  tags-file-name set.
  1263.     ;;  To get around this.  I'm setting this variable in the TAGS buffer.
  1264.     ;; Skip this in XEmacs (Changed by Anders Stenman)
  1265.     (if (and (not (string-match "XEmacs\\|Lucid" emacs-version))
  1266.              (get-file-buffer the-tags-file))
  1267.     (save-excursion
  1268.       (set-buffer (get-file-buffer the-tags-file))
  1269.       (set (make-local-variable 'tags-file-name) the-tags-file))))
  1270.  
  1271.   
  1272.   (if bib-document-TeX-files-warnings   ;free variable loose in emacs!
  1273.       (progn
  1274.         (with-output-to-temp-buffer "*Help*" 
  1275.           (princ bib-document-TeX-files-warnings))
  1276.         (setq bib-document-TeX-files-warnings nil) ;Reset
  1277.         (bib-cite-fontify-red))))
  1278.  
  1279. (defun bib-Is-hidden ()
  1280.   "Return true is current point is hidden"
  1281.   (if (not selective-display)
  1282.       nil                               ;Not hidden if not using this...
  1283.     (save-excursion
  1284.       (if (not (re-search-backward "[\n\^M]" nil t))
  1285.           nil                           ;Play safe
  1286.         (if (string-equal (buffer-substring (match-beginning 0)(match-end 0))
  1287.                           "\n")
  1288.             nil
  1289.           t)))))
  1290.  
  1291. (defun bib-highlight-mouse ()
  1292.   "Make that nice green highlight when the mouse is over LaTeX commands"
  1293.   (interactive)
  1294. ;;;Comment this out.  User should be able to use bib-highlight-mouse
  1295. ;;;to try it out regardless of bib-highlight-mouse-t.  
  1296. ;;;Check bib-highlight-mouse-t only in automated cases.
  1297. ;;;
  1298. ;;;  (if (and bib-highlight-mouse-t
  1299. ;;;           ;;window-system)        ;Do nothing unless under X
  1300. ;;;           )
  1301. ;;; *all of code was here*
  1302. ;;;      )
  1303.   (save-excursion
  1304.     (let ((s)(e)(extent)(local-extent-list bib-ext-list)
  1305.           (inhibit-read-only t)
  1306.           (modified (buffer-modified-p))) ;put-text-property changing this?
  1307.       ;; * peta Wed Nov  8 16:27:29 1995 -- better remove the mouse face
  1308.       ;;   properties first.
  1309.       (setq bib-ext-list nil)        ;Reconstructed below...
  1310.       (if (string-match "XEmacs\\|Lucid" emacs-version)
  1311.           (while local-extent-list
  1312.         (setq extent (car local-extent-list))
  1313.          (if (or (extent-detached-p extent)
  1314.              (and (<= (point-min)(extent-start-position extent))
  1315.               (>= (point-max)(extent-end-position extent))))
  1316.         (delete-extent extent)
  1317.           (setq bib-ext-list (cons extent bib-ext-list)))
  1318.             (setq local-extent-list (cdr local-extent-list)))
  1319.         ;; Remove properties for regular emacs
  1320.         ;; FIXME This detroys all mouse-faces and local-maps!
  1321.         ;; FIXME Hope no other package is using them in this buffer!
  1322.         (let ((before-change-functions) (after-change-functions))
  1323.           (remove-text-properties (point-min) (point-max)
  1324.                                   '(mouse-face t local-map t))))
  1325.       (goto-char (point-min))
  1326.       (while 
  1327.           (re-search-forward 
  1328.            "\\\\\\(ref\\|label\\|[A-Za-z]*cite[A-Za-z]*\\(\\[.*\\]\\)?\\){[^}]*}"
  1329.            nil t)
  1330.         (setq s (match-beginning 0))
  1331.         (setq e (match-end 0))
  1332.         (cond 
  1333.          ((string-match "XEmacs\\|Lucid" emacs-version)
  1334.           (setq extent (make-extent s e))
  1335.           (setq bib-ext-list (cons extent bib-ext-list))
  1336.           (set-extent-property extent 'highlight t)
  1337.           (set-extent-property extent 'start-open t)
  1338.       (set-extent-property extent 'balloon-help 'bib-label-help)
  1339.       (set-extent-property extent 'help-echo 'bib-label-help-echo)
  1340.           (set-extent-property extent 'keymap bib-highlight-mouse-keymap))
  1341.          (t
  1342.           (let ((before-change-functions) (after-change-functions)
  1343.                 ;;(this-overlay (make-overlay s e))
  1344.                 )
  1345. ;;; Even using overlays doens't help here.  If bib-highlight-mouse-keymap
  1346. ;;; does not include the AucTeX menus, then these disappear when we click
  1347. ;;; onto a \cite command.  Perhaps using bib-cite as a minor mode will fix
  1348. ;;; this?  For now, bib-cite must be loaded after these menus are built.
  1349. ;;; It must therefore be loaded in a mode-hook.
  1350.             (put-text-property s e 'local-map bib-highlight-mouse-keymap)
  1351.             (put-text-property s e 'mouse-face 'highlight)
  1352.           ;;(overlay-put this-overlay 'local-map bib-highlight-mouse-keymap)
  1353.           ;;(overlay-put this-overlay 'mouse-face 'highlight)
  1354.             ))))
  1355.       (set-buffer-modified-p modified))))
  1356.  
  1357. (defun bib-toggle-highlight () 
  1358. ;; FIXME: do something about after-change stuff?
  1359.   (interactive)
  1360.   (if (setq bib-highlight-mouse-t (not bib-highlight-mouse-t))
  1361.       (bib-highlight-mouse)
  1362.     (let ((modified (buffer-modified-p))
  1363.       (inhibit-read-only t))
  1364.       (cond 
  1365.        ((string-match "XEmacs\\|Lucid" emacs-version)
  1366.         (while bib-ext-list
  1367.           (delete-extent (car bib-ext-list))
  1368.           (setq bib-ext-list (cdr bib-ext-list))))
  1369.        (t
  1370.         (let ((before-change-functions) (after-change-functions))
  1371.           (remove-text-properties (point-min) (point-max) 
  1372.                                   '(mouse-face local-map)))))
  1373.       (set-buffer-modified-p modified))))
  1374.  
  1375. (defun bib-label-help-echo (object)
  1376.   (if bib-label-help-echo-format
  1377.       (bib-label-help object bib-label-help-echo-format)))
  1378.  
  1379. ;;; Balloon-help callback. Anders Stenman <stenman@isy.liu.se>
  1380. (defun bib-label-help (object &optional format)
  1381.   (or format (setq format "Use mouse button 2 to find the %s.
  1382. Use mouse button 3 to display the %s."))
  1383.   (save-match-data
  1384.     (let* ((string (extent-string object))
  1385.        (type (cond ((string-match "^\\\\cite" string) "citation")
  1386.                ((string-match "^\\\\ref" string) "\\label{}")
  1387.                ((string-match "^\\\\label" string) "\\ref{}")
  1388.                (t "bullshit"))))
  1389.       (format format type type))))
  1390.  
  1391. ;;----------------------------------------------------------------------------
  1392. ;; Routines to display or edit a citation's bibliography
  1393.  
  1394. (defun bib-display-citation ()
  1395.   "Do the displaying of cite info.  Returns t if found cite key, nil otherwise.
  1396. Example with cursor located over cite command or arguments:
  1397. \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
  1398.    ^Display-all-citations          ^Display-this-citation"
  1399.   (save-excursion
  1400.     (let* ((the-keys-obarray (bib-get-citekeys-obarray)) ;1st in case of error
  1401.            (work-buffer (get-buffer-create "*bibtex-work*"))
  1402.            (bib-buffer (bib-get-bibliography nil))
  1403.            (the-warnings (bib-get-citations 
  1404.                           the-keys-obarray
  1405.                           bib-buffer
  1406.                           work-buffer
  1407.                           bib-substitute-string-in-display))
  1408.            (the-warn-point))
  1409.       (if the-warnings
  1410.           (progn 
  1411.             (set-buffer work-buffer)
  1412.             (goto-char 1)
  1413.             (insert the-warnings)
  1414.             (setq the-warn-point (point))))
  1415.       (with-output-to-temp-buffer 
  1416.           "*Help*" 
  1417.         (set-buffer work-buffer)
  1418.         (princ (buffer-substring 1 (point-max))))
  1419.       (bib-cite-fontify-help-as-bibtex)
  1420.       (if the-warn-point
  1421.           (bib-cite-fontify-red the-warn-point))
  1422.       (kill-buffer bib-buffer)
  1423.       (kill-buffer work-buffer))))
  1424.  
  1425. (defun bib-edit-citation ()
  1426.   "Do the edit of cite info.  Returns t if found cite key, nil otherwise.
  1427. Find and and put edit point in bib file associated with a BibTeX citation
  1428. under cursor from \bibliography input file.
  1429. In a multi-entry cite command, the cursor should be on the actual cite key
  1430. desired (otherwise a random entry will be selected). 
  1431. e.g.: \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
  1432.                         ^Display-this-citation"
  1433.   (let ((the-keys-obarray (bib-get-citekeys-obarray)) ;1st in case of error
  1434.         (bib-buffer (bib-get-bibliography t))
  1435.         (the-key)(the-file))
  1436.     (save-excursion
  1437.       (mapatoms                     ;Do this for each cite-key found...
  1438.        (function (lambda (cite-key) 
  1439.                    (setq the-key (symbol-name cite-key))))
  1440.        the-keys-obarray)
  1441.       (set-buffer bib-buffer)
  1442.       (goto-char (point-min))
  1443.       (if (not (re-search-forward 
  1444.                 (concat "@[^{(]+[{(][\t ]*" (regexp-quote the-key) "[ ,\n]")
  1445.                 nil t))
  1446.           (progn 
  1447.             (kill-buffer bib-buffer)
  1448.             (error "Sorry, could not find bib entry for %s" the-key))
  1449.         (re-search-backward "%%%Filename: \\([^\n]*\\)" nil t)
  1450.         (setq the-file (buffer-substring (match-beginning 1)(match-end 1)))
  1451.         (kill-buffer bib-buffer)))
  1452. ;;; (find-file the-file)
  1453.     (funcall bib-switch-to-buffer-function (find-file-noselect the-file))
  1454.     (goto-char (point-min))             ;V2.19 fix
  1455.     (re-search-forward (concat "@[^{(]+[{(][\t ]*" 
  1456.                                (regexp-quote the-key) 
  1457.                                "[ ,\n]") nil t)))
  1458.  
  1459. ;;--------------------------------------------------------------------------
  1460. ;; Function for bib-apropos
  1461.  
  1462. (defun bib-apropos-keyword-at-point ()
  1463.   ;; Returns the keyword under point for initial input to bib-apropos prompt
  1464.   (save-excursion
  1465.     (let ((here (point)))
  1466.       (cond
  1467.        ((and (re-search-backward "[\n{, ]" nil t)
  1468.              (string-equal "{" (buffer-substring (match-beginning 0)
  1469.                                                  (match-end 0))))
  1470.         (if (fboundp 'buffer-substring-no-properties)
  1471.             (buffer-substring-no-properties (1+ (point)) here)
  1472.         (buffer-substring (1+ (point)) here)))))))
  1473.  
  1474. ;;--------------------------------------------------------------------------
  1475. ;; Functions for Displaying or moving to matching \ref or \label command
  1476.  
  1477. (defun bib-display-label ()
  1478. ;;  "Display environment associated with a label or first ref assoc. with label
  1479. ;;The label or ref name is extracted from the text under the cursor, or the
  1480. ;;user is prompted is nothing suitable is found.  The first prompt is for a
  1481. ;;label. If you answer with an empty string, a second prompt for a ref will
  1482. ;;be given."
  1483.   (let ((the-name (bib-guess-or-prompt-for-label)))
  1484.     (if (not the-name)
  1485.         (message "No name given")
  1486.       (bib-display-or-find-label the-name t))))
  1487.  
  1488. (defun bib-find-label ()
  1489.   "Move to a label, or the first occurance of a ref.
  1490. The label or ref name is extracted from the text under the cursor. 
  1491. ;;If nothing suitable is found, the user is prompted. The first prompt is for a
  1492. ;;label. If you answer with an empty string, a second prompt for a ref will be 
  1493. ;;given.
  1494. ;;
  1495. ;;If within a single file document:
  1496. ;;  You can move back with C-x C-x as the mark is set before moving.
  1497. ;;  You can search for next occurrances of a ref command with C-s C-s.
  1498. ;;
  1499. ;;If within a multi-file document (in auctex only)
  1500. ;;  You can move back with C-x C-x if within the same buffer.  If not, just
  1501. ;;  select your previous buffer.
  1502. ;;  You can search for next occurrances of a ref command with tag commands:
  1503. ;;     C-u M-.     Find next alternate definition of last tag specified.
  1504. ;;     C-u - M-.   Go back to previous tag found."
  1505.   (let ((the-name (bib-guess-or-prompt-for-label)))
  1506.     (if (not the-name)
  1507.         (message "No name given")
  1508.       (bib-display-or-find-label the-name nil))))
  1509.  
  1510. ;;--------------------------------------------------------------------------
  1511. ;; Functions for Displaying or moving to matching \ref or \label command
  1512.  
  1513. (defun bib-display-or-find-label (the-name displayf)
  1514. ;; work horse for bib-find-label and bib-display-label
  1515.   (let* ((masterfile (bib-master-file))
  1516.          (masterdir (and masterfile
  1517.                          (file-name-directory masterfile)))
  1518.          (new-point)(new-buffer))
  1519.     (save-excursion
  1520.       ;; Now we are either in a simple file, or with a multi-file document
  1521.       (cond
  1522.        (masterfile                   ;Multi-file document
  1523.         (cond 
  1524.          (displayf                  ;Display only
  1525.           (set-buffer (bib-etags-find-noselect the-name masterdir))
  1526.           (re-search-forward (regexp-quote the-name) nil t) 
  1527.           ;; ...because tags puts point on beginning of line
  1528.           (if (string-match "^\\\\label" the-name)
  1529.               (bib-display-this-environment) ;display the label's environment
  1530.             (bib-display-this-ref)))    ;     display the ref's context
  1531.          (t                         ;Move to it
  1532.           (setq new-buffer (bib-etags-find-noselect the-name masterdir))
  1533.           (if bib-novice
  1534.               (message
  1535.                (substitute-command-keys
  1536.                 (concat "Use C-u \\[find-tag] to find the next occurrence; "
  1537.                         "Use C-u - \\[find-tag] to find the previous."))))
  1538.           (if (equal new-buffer (current-buffer))
  1539.               (setq new-point (point))) ;Moving with the same buffer
  1540.           (and (string-match "^\\\\ref" the-name)
  1541.                (setq search-ring (cons the-name search-ring))))))
  1542.        (t                           ;Single-file document
  1543.         (goto-char (point-min))
  1544.         (if (search-forward the-name nil t)
  1545.             (if displayf
  1546.                 (if (string-match "^\\\\label" the-name)
  1547.                     (bib-display-this-environment)   ;Display the environment
  1548.                   (bib-display-this-ref)) ;           display the ref's context
  1549.               (setq new-point (match-beginning 0))  ;or move there
  1550.               (if bib-novice
  1551.                   (message
  1552.                    (substitute-command-keys
  1553.                     (concat 
  1554.                      "Use \\[isearch-forward] \\[isearch-forward] to find the "
  1555.                      "next occurrence; Use C-x C-x to go back."))))
  1556.               (if (string-match "^\\\\ref" the-name)
  1557.                   (setq search-ring (cons the-name search-ring))
  1558.                 (setq search-ring (cons (concat "\\ref" (substring the-name 6))
  1559.                                         search-ring))))
  1560.           (message "Sorry, cannot find %s" the-name)))))
  1561.     (if new-point
  1562.         (progn
  1563.           (push-mark (point) t nil)   ;We've moving there... push mark
  1564.           (goto-char new-point))
  1565.       (if new-buffer                    ;We've changing buffer
  1566. ;;         (switch-to-buffer new-buffer)
  1567.            (funcall bib-switch-to-buffer-function new-buffer)))
  1568.     (if (bib-Is-hidden)
  1569.         (save-excursion
  1570.           (beginning-of-line)
  1571.           (show-entry)))))
  1572.  
  1573. (defvar bib-label-prompt-map nil)
  1574. (if bib-label-prompt-map
  1575.     ()
  1576.   (setq bib-label-prompt-map (copy-keymap minibuffer-local-completion-map))
  1577.   (define-key bib-label-prompt-map " " 'self-insert-command))
  1578.  
  1579. (defun bib-guess-or-prompt-for-label ()
  1580.   ;; Guess from context, or prompt the user for a label command
  1581.   (save-excursion
  1582.     (if (not (looking-at "\\\\"))        ;If not on beginning of a command
  1583.              (re-search-backward "[\\]" 
  1584.                                  (save-excursion (beginning-of-line)(point)) 
  1585.                                  t))
  1586.     (cond
  1587.      ((looking-at "\\\\ref{")           ;On \ref, looking for matching \label
  1588.       (let ((b (progn (search-forward "{" nil t)(forward-char -1)(point)))
  1589.             (e (progn (forward-sexp 1)(point))))
  1590.         (concat "\\label" (buffer-substring b e))))
  1591.      ((looking-at "\\\\label{")         ;On \label, looking for matching \ref
  1592.       (let ((b (progn (search-forward "{" nil t)(forward-char -1)(point)))
  1593.             (e (progn (forward-sexp 1)(point))))
  1594.         (concat "\\ref" (buffer-substring b e))))
  1595.      (t                                 ;Prompt the user
  1596.       (let* ((minibuffer-local-completion-map bib-label-prompt-map)
  1597.          (the-alist (create-alist-from-list 
  1598.                          (cdr (reverse LaTeX-label-list))))
  1599.         ;;; LaTeX-label-list example: 
  1600.         ;;;  '(("label3" "label4")("label1" "label2") nil)
  1601.         ;; so let's get rid of that nil part in embedded list.
  1602.              (the-name 
  1603.               (if (string-equal "18" (substring emacs-version 0 2))
  1604.                   (completing-read "Label: " the-alist nil nil nil)
  1605.                 (completing-read "Label: " the-alist nil nil nil 
  1606.                                  'LaTeX-find-label-hist-alist))))
  1607.         (if (not (equal the-name ""))
  1608.             (concat "\\label{" the-name "}")
  1609.           ;; else try to get a \ref
  1610.           (if (string-equal "18" (substring emacs-version 0 2))
  1611.               (setq the-name (completing-read "Ref: " the-alist nil nil nil))
  1612.             (setq the-name (completing-read "Ref: " the-alist nil nil nil 
  1613.                                             'LaTeX-find-label-hist-alist)))
  1614.           (if (not (equal the-name ""))
  1615.               (concat "\\ref{" the-name "}")
  1616.             nil)))))))
  1617.  
  1618. (defun bib-display-this-ref ()
  1619.   "Display a few lines around current point"
  1620.   (cond 
  1621.    ((bib-Is-hidden)
  1622.     (with-output-to-temp-buffer "*BiBTemp*" 
  1623.       (princ 
  1624.        (buffer-substring 
  1625.         (save-excursion
  1626.           (let ((i 3))
  1627.             (while (and (> i 0)
  1628.                         (re-search-backward "[\n\^M]" nil t)
  1629.                         (setq i (1- i)))))
  1630.           (point))
  1631.         (save-excursion
  1632.           (let ((i 3))
  1633.             (while (and (> i 0)
  1634.                         (re-search-forward "[\n\^M]" nil t)
  1635.                         (setq i (1- i)))))
  1636.           (point)))))
  1637.     (set-buffer "*BiBTemp*")
  1638.     (while (search-forward "\^M" nil t)
  1639.       (replace-match "\n" nil t))
  1640.     (goto-char 1)
  1641.     (if (looking-at "\n")  ;Remove first empty line...
  1642.         (delete-char 1))
  1643.     (with-output-to-temp-buffer "*Help*" 
  1644.       (princ (buffer-substring 1 (point-max))))
  1645.     (bib-cite-fontify-help-as-latex)
  1646.     (kill-buffer "*BiBTemp*"))
  1647.    (t 
  1648.     (with-output-to-temp-buffer ;     display the ref's context
  1649.         "*Help*" 
  1650.       (princ 
  1651.        (buffer-substring (save-excursion (forward-line -2)(point))
  1652.                          (save-excursion (forward-line 3)(point)))))
  1653.     (bib-cite-fontify-help-as-latex))))
  1654.  
  1655. (defun bib-display-this-environment ()
  1656.   "Display the environment associated with a label, or its section name
  1657. Assumes point is already on the label.
  1658. Does not save excursion."
  1659. ;; Bugs:  The method used here to detect the environment is *not* foolproof.
  1660. ;;        It will get confused, for example, between two figure environments,
  1661. ;;        picking out both instead of the section label above them.  But since
  1662. ;;        users typically puts their labels next to the section declaration,
  1663. ;;        I'm satisfied with this... for now.
  1664. ;; I could have used the following auc-tex functions:
  1665. ;;  LaTeX-current-environment
  1666. ;;    Function: Return the name (a string) of the enclosing LaTeX environment.
  1667. ;;  LaTeX-current-section
  1668. ;;    Function: Return the level of the section that contain point.
  1669. ;; but then this code would only work as part of auc-tex...
  1670.   (let ((the-point (point))
  1671.         (end-point (point))
  1672.         (the-environment)(foundf))
  1673.     (while (and (not foundf)
  1674.                 (goto-char end-point) ;Past end of last search
  1675.                 (re-search-forward "\\(^\\|\^M\\)[ \t]*\\\\end{\\([^}]*\\)}" 
  1676.                                    nil t))
  1677.       (setq end-point (point))
  1678.       (setq the-environment (buffer-substring (match-beginning 2)
  1679.                                               (match-end 2)))
  1680.       (and (not (string-match "document" the-environment))
  1681.            (re-search-backward (concat "\\(^\\|\^M\\)[ \t]*\\\\begin{" 
  1682.                                        (regexp-quote the-environment) "}"))
  1683.            (<= (point) the-point)
  1684.            (setq foundf t)))
  1685.     (if foundf                          ;A good environment
  1686.         (progn
  1687.           (cond ((bib-Is-hidden)        ;Better way is: replace-within-string
  1688.                  (with-output-to-temp-buffer "*BiBTemp*" 
  1689.                    (princ (buffer-substring (point) end-point)))
  1690.                  (set-buffer "*BiBTemp*")
  1691.                  (while (search-forward "\^M" nil t)
  1692.                    (replace-match "\n" nil t))
  1693.                  (goto-char 1)
  1694.                  (if (looking-at "\n")  ;Remove first empty line...
  1695.                      (delete-char 1))
  1696.                  (with-output-to-temp-buffer "*Help*" 
  1697.                    (princ (buffer-substring 1 (point-max))))
  1698.                  (kill-buffer "*BiBTemp*"))
  1699.                 (t
  1700.                  (with-output-to-temp-buffer "*Help*" 
  1701.                    (princ (buffer-substring (point) end-point)))))
  1702.           (bib-cite-fontify-help-as-latex))
  1703.       ;; Just find the section declaration
  1704.       (goto-char the-point)
  1705.       (if (re-search-backward
  1706.            "\\(^\\|\^M\\)[ \t]*\\\\\\(sub\\)*section{\\([^}]*\\)}" nil t)
  1707.           (message (buffer-substring (match-beginning 0)(match-end 0)))
  1708.         (error 
  1709.          "Sorry, could not find an environment or section declaration")))))
  1710.  
  1711. (defvar LaTeX-find-label-hist-alist nil "History list for LaTeX-find-label")
  1712. (defvar LaTeX-label-list nil "Used by auc-tex to store label names")
  1713.  
  1714.           
  1715. (defun create-alist-from-list (the-list)
  1716. ;;; Return a single list from a list that may contain either items
  1717. ;;; or any number of list levels containing items.
  1718. ;;; e.g. turns
  1719. ;;;  '(("label3" "label4")("label1" "label2") "label")
  1720. ;;; into  
  1721. ;;;  '(("label3") ("label4") ("label1") ("label2") ("label"))
  1722.   (mapcar 'list (bib-cite-mh-list-to-string the-list)))
  1723.  
  1724. ;;;
  1725. ;;; Following two functions from mh-utils.el (part of GNU emacs)
  1726. ;;; I have changed the names in case these functions change what they do.
  1727. ;;;
  1728.  
  1729. (defun bib-cite-mh-list-to-string (l)
  1730.   ;; Flattens the list L and makes every element of the new list into a string.
  1731.   (nreverse (bib-cite-mh-list-to-string-1 l)))
  1732.  
  1733. (defun bib-cite-mh-list-to-string-1 (l)
  1734.   (let ((new-list nil))
  1735.     (while l
  1736.       (cond ((null (car l)))
  1737.         ((symbolp (car l))
  1738.          (setq new-list (cons (symbol-name (car l)) new-list)))
  1739.         ((numberp (car l))
  1740.          (setq new-list (cons (int-to-string (car l)) new-list)))
  1741.         ((equal (car l) ""))
  1742.         ((stringp (car l)) (setq new-list (cons (car l) new-list)))
  1743.         ((listp (car l))
  1744.          (setq new-list (nconc (bib-cite-mh-list-to-string-1 (car l))
  1745.                    new-list)))
  1746.         (t (error "Bad element in mh-list-to-string: %s" (car l))))
  1747.       (setq l (cdr l)))
  1748.     new-list))
  1749.  
  1750. ;; -------------------------------------------------------------------------
  1751. ;; Routines to extract cite keys from text
  1752.  
  1753. ;;    ... is truly remarkable, as shown in \citeN{Thomson77,Test56}. Every
  1754. ;; \cite[{\it e.g.}]{Thomson77,Test56}
  1755.  
  1756. (defun bib-get-citations (keys-obarray bib-buffer new-buffer substitute)
  1757.   "Put citations of KEYS-OBARRAY from BIB-BUFFER into NEW-BUFFER,
  1758. Substitute strings if SUBSTITUTE is t
  1759. Return the-warnings as text."
  1760.   (let ((the-warnings)                  ;The only variable to remember...
  1761.         (case-fold-search t))           ;All other results go into new-buffer
  1762.     ;; bibtex is not case-sensitive for keys.
  1763.     (save-excursion
  1764.       (let ((the-text))
  1765.         (set-buffer bib-buffer)
  1766.         (mapatoms                         ;Do this for each cite-key found...
  1767.          (function 
  1768.           (lambda (cite-key) 
  1769.             (goto-char (point-min))
  1770.             (if (re-search-forward 
  1771.                  (concat "@[^{(]+[{(][\t ]*" 
  1772.                          (regexp-quote (symbol-name cite-key)) 
  1773.                          "\\([, ]\\\|$\\)")
  1774.                 ;;            ^^     ^  comma, space or end-of-line
  1775.                  nil t)
  1776.                 (setq the-text (concat the-text
  1777.                                        (buffer-substring 
  1778.                                         (progn (beginning-of-line)(point))
  1779.                                         (progn (forward-sexp 2)(point)))
  1780.                                        "\n\n"))
  1781.               (setq the-warnings (concat the-warnings 
  1782.                                          "Cannot find entry for: " 
  1783.                                          (symbol-name cite-key) "\n")))))
  1784.          keys-obarray)
  1785.         (if (not the-text) 
  1786.             (error "Sorry, could not find any of the references"))
  1787.         ;; Insert the citations in the new buffer
  1788.         (set-buffer new-buffer)
  1789.         (insert the-text)
  1790.         (goto-char 1))
  1791.  
  1792.       ;; We are at beginning of new-buffer.
  1793.       ;; Now handle crossrefs
  1794.       (let ((crossref-obarray (make-vector 201 0)))
  1795.         (while (re-search-forward
  1796.                 "[, \t]*crossref[ \t]*=[ \t]*\\(\"\\|\{\\)" nil t)
  1797.           ;;handle {text} or "text" cases
  1798.           (if (string-equal "{" (buffer-substring (match-beginning 1)
  1799.                                                   (match-end 1)))
  1800.               (re-search-forward "[^\}]+" nil t)
  1801.             (re-search-forward "[^\"]+" nil t))
  1802.           (intern (buffer-substring (match-beginning 0)(match-end 0)) 
  1803.                   crossref-obarray))
  1804.         ;; Now find the corresponding keys,
  1805.         ;; but add them only if not already in `keys-obarray'
  1806.         (set-buffer bib-buffer)
  1807.         (goto-char 1)
  1808.         (let ((the-text))
  1809.           (mapatoms                     ;Do this for each crossref key found...
  1810.            (function
  1811.             (lambda (crossref-key)
  1812.               (if (not (intern-soft (symbol-name crossref-key) keys-obarray))
  1813.                   (progn
  1814.                     ;; Not in keys-obarray, so not yet displayed.
  1815.                     (goto-char (point-min))
  1816.                     (if (re-search-forward 
  1817.                          (concat "@[^{(]+[{(][\t ]*" 
  1818.                                  (regexp-quote (symbol-name crossref-key)) 
  1819.                                  "\\(,\\|$\\)") 
  1820.                          nil t)
  1821.                         (setq the-text 
  1822.                               (concat the-text
  1823.                                       (buffer-substring 
  1824.                                        (progn (beginning-of-line)(point))
  1825.                                        (progn (forward-sexp 2)(point)))
  1826.                                       "\n\n"))
  1827.                       (setq the-warnings 
  1828.                             (concat the-warnings 
  1829.                                     "Cannot find crossref entry for: " 
  1830.                                     (symbol-name crossref-key) "\n")))))))
  1831.            crossref-obarray)
  1832.           ;; Insert the citations in the new buffer
  1833.           (set-buffer new-buffer)
  1834.           (goto-char (point-max))
  1835.           (if the-text
  1836.               (insert the-text)))
  1837.         (goto-char 1))
  1838.  
  1839.       ;; Now we have all citations in new-buffer, collect all used @String keys
  1840.       ;; Ex:  journal =      JPO,
  1841.       (let ((strings-obarray (make-vector 201 0)))
  1842.         (while (re-search-forward bib-string-regexp nil t)
  1843.           (intern (buffer-substring (match-beginning 1)(match-end 1)) 
  1844.                   strings-obarray))
  1845.         ;; Now find the corresponding @String commands
  1846.         ;; Collect either the @string commands, or the string to substitute
  1847.         (set-buffer bib-buffer)
  1848.         (goto-char 1)
  1849.         (let ((string-alist)
  1850.               (the-text))
  1851.           (mapatoms                     ;Do this for each string-key found...
  1852.            (function
  1853.             (lambda (string-key)
  1854.               (goto-char (point-min))
  1855.               ;; search for @string{ key = {text}} or @string{ key = "text"}
  1856.               (if (re-search-forward
  1857.                    (concat "^[ \t]*@string[{(]"
  1858.                            (regexp-quote (symbol-name string-key))
  1859.                            "[\t ]*=[\t ]*\\(\"\\|\{\\)")
  1860.                    nil t)
  1861.                   (let ((the-string-start (1- (match-end 1))) ;catch bracket
  1862.                         ;;handle {text} or "text" cases
  1863.                         (the-string-end
  1864.                          (cond 
  1865.                           ((string-equal "\"" 
  1866.                                          (buffer-substring (match-beginning 1)
  1867.                                                            (match-end 1)))
  1868.                            
  1869.                            (re-search-forward "[^\\]\"" nil t)
  1870.                            (point))
  1871.                           (t
  1872.                            (forward-char -1)
  1873.                            (forward-list 1)
  1874.                            (point)))))
  1875.                     (if substitute      ;Collect substitutions
  1876.                         (setq string-alist
  1877.                               (append
  1878.                                string-alist
  1879.                                (list 
  1880.                                 (cons (symbol-name string-key) 
  1881.                                       (regexp-quote
  1882.                                        (buffer-substring the-string-start
  1883.                                                          the-string-end))))))
  1884.                       ;;Collect the strings command themseves
  1885.                       (setq the-text
  1886.                             (concat the-text 
  1887.                                     (buffer-substring 
  1888.                                      (progn (forward-char 1)(point))
  1889.                                      (re-search-backward "^[ \t]*@string[{(]" 
  1890.                                                          nil t))
  1891.                                     "\n"))))
  1892.                 ;; @string entry not found
  1893.                 (if (not (member (symbol-name string-key) 
  1894.                                  bib-string-ignored-warning))
  1895.                     (setq the-warnings 
  1896.                           (concat the-warnings 
  1897.                                   "Cannot find @String entry for: " 
  1898.                                   (symbol-name string-key) "\n"))))))
  1899.            strings-obarray)
  1900.           ;; Now we have `the-text' of @string commands, 
  1901.           ;; or the `string-alist' to substitute.
  1902.           (set-buffer new-buffer)
  1903.           (if substitute
  1904.               (while string-alist
  1905.                 (goto-char 1)
  1906.                 (let ((the-key (car (car string-alist)))
  1907.                       (the-string (cdr (car string-alist))))
  1908.                   (while (re-search-forward 
  1909.                           (concat "\\(^[, \t]*[a-zA-Z]+[ \t]*=[ \t]*\\)" 
  1910.                                   (regexp-quote the-key) 
  1911.                                   "\\([, \t\n]\\)")
  1912.                           nil t)
  1913.                     (replace-match (concat "\\1" the-string "\\2") t)))
  1914.                 (setq string-alist (cdr string-alist)))
  1915.             ;; substitute is nil; Simply insert text of @string commands
  1916.             (goto-char 1)
  1917.             (if the-text 
  1918.                 (insert the-text "\n")))
  1919.           (goto-char 1))))
  1920.  
  1921.     ;; We are done!
  1922.     ;; Return the warnings...
  1923.     the-warnings))
  1924.  
  1925. (defun bib-get-citekeys-obarray ()
  1926.   "Return obarray of citation key (within curly brackets) under cursor."
  1927.   (save-excursion
  1928.     ;; First find *only* a key *within a cite command
  1929.     (let ((the-point (point))
  1930.           (keys-obarray (make-vector 201 0)))
  1931.       ;; First try to match a cite command
  1932.       (if (and (skip-chars-backward "a-zA-Z") ;Stops on \ or {
  1933.                (looking-at "[a-zA-Z]*cite[a-zA-Z]*"))
  1934.           (progn
  1935.             ;;skip over any optional arguments to \cite[][]{key} command
  1936.             (skip-chars-forward "a-zA-Z")
  1937.             (while (looking-at "\\[")
  1938.                 (forward-list 1))
  1939.             (re-search-forward "{[ \n]*\\([^,} \n]+\\)" nil t)
  1940.             (intern (buffer-substring (match-beginning 1)(match-end 1))
  1941.                     keys-obarray)
  1942.             (while (and (skip-chars-forward " \n") ;no effect on while
  1943.                         (looking-at ","))
  1944.               (forward-char 1)
  1945.               ;;The following re-search skips over leading spaces
  1946.               (re-search-forward "\\([^,} \n]+\\)" nil t) 
  1947.               (intern (buffer-substring (match-beginning 1)(match-end 1))
  1948.                       keys-obarray)))
  1949.             
  1950.         ;; Assume we are on the keyword
  1951.         (goto-char the-point)
  1952.         (let ((the-start (re-search-backward "[\n{, ]" nil t))
  1953.               (the-end (progn (goto-char the-point)
  1954.                               (re-search-forward "[\n}, ]" nil t))))
  1955.           (if (and the-start the-end)
  1956.               (intern (buffer-substring (1+ the-start) (1- the-end))
  1957.                       keys-obarray)
  1958.             ;; Neither...
  1959.             (error "Sorry, can't find a reference here"))))
  1960.       keys-obarray)))
  1961.  
  1962. (defun bib-buffer-citekeys-obarray ()
  1963.   "Extract citations keys used in the current buffer"
  1964.   (let ((keys-obarray (make-vector 201 0)))
  1965.     (save-excursion
  1966.       (goto-char (point-min))
  1967.       ;; Following must allow for \cite[e.g.][]{key} !!!
  1968.       ;; regexp for \cite{key1,key2} was "\\\\[a-Z]*cite[a-Z]*{\\([^,}]+\\)"
  1969.       (while (re-search-forward "\\\\[a-zA-Z]*cite[a-zA-Z]*\\(\\[\\|{\\)" 
  1970.                                 nil t)
  1971.         (backward-char 1)
  1972.         (while (looking-at "\\[")       ; ...so skip all bracketted options
  1973.           (forward-sexp 1))
  1974.         ;; then lookup first key
  1975.         (if (looking-at "{[ \n]*\\([^,} \n]+\\)")
  1976.             (progn
  1977.               (intern (buffer-substring (match-beginning 1)(match-end 1)) 
  1978.                       keys-obarray)
  1979.               (goto-char (match-end 1))
  1980.               (while (and (skip-chars-forward " \n")
  1981.                           (looking-at ","))
  1982.                 (forward-char 1)
  1983.                 (re-search-forward "\\([^,} \n]+\\)" nil t) 
  1984.                 (intern (buffer-substring (match-beginning 1)(match-end 1))
  1985.                         keys-obarray)))))
  1986.       (if keys-obarray
  1987.           keys-obarray
  1988.         (error "Sorry, could not find any citation keys in this buffer.")))))
  1989.  
  1990. ;;---------------------------------------------------------------------------
  1991. ;; Multi-file document programming requirements:
  1992. ;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1993. ;; bib-make-bibliography
  1994. ;;    bib-document-citekeys-obarray needs the master .aux file to extract
  1995. ;;   citation keys.
  1996. ;;    Included .aux files (corresponding to \include'd LaTeX files) are 
  1997. ;;   then specified relative to the master-file-directory.
  1998. ;;
  1999. ;; bib-get-bibliography (used by interactive commands to extract bib sources)
  2000. ;;  
  2001. ;;    bibtex source filenames are returned from (LaTeX-bibliography-list)
  2002. ;;   unformatted.  Since only a single \bibliogragrphy command is allowed 
  2003. ;;   by BiBTeX in a document, it is safe to assume that their path is 
  2004. ;;   relative to the master file's directory (since the path is relative 
  2005. ;;   to where the BiBTeX program is actually ran).
  2006. ;;
  2007. ;; imenu
  2008. ;;
  2009. ;;    Requires list of all tex files (complete with paths) to call etags on 
  2010. ;;   them.
  2011. ;;    I used (TeX-style-list) to get the list of possible tex files, but
  2012. ;;   they are not in sorted order.  Therefore the imenu would be somewhat
  2013. ;;   confusing. I'll have to do the scan myself, except that I'll only be 
  2014. ;;   looking at the master file for \include statements.
  2015.  
  2016. ;; (See TeX-check-files, used in TeX-save-document.  All documents related 
  2017. ;;  files are returned by (TeX-style-list) and stored in TeX-active-styles.  
  2018. ;;  Original idea was to search TeX-check-path for files listed in 
  2019. ;;  TeX-active-styles (with possible relative or full paths) that end in .tex.)
  2020.  
  2021. (defun bib-master-directory ()
  2022. ;; Returns the directory associated with the master file.
  2023. ;; If no master file, then return current default.
  2024.   (let ((masterfile (bib-master-file)))
  2025.     (if masterfile 
  2026.         (file-name-directory (expand-file-name (TeX-master-file)))
  2027.       default-directory)))
  2028.  
  2029. (defun bib-master-file ()
  2030. ;; return master file full path, or nil if not a multi-file document
  2031. ;; I wish there were a better way to tell about non multi-file documents...
  2032.   (let ((master
  2033.          (cond
  2034.           ((not (boundp 'TeX-master))
  2035.            ;; This buffer doesn't know what a master file is, so return now.
  2036.            nil)
  2037.           ((and TeX-master              ;Set, but not to t
  2038.                 (not (eq TeX-master 't))) ; then we have an actual name
  2039.            (expand-file-name TeX-master))
  2040.           ((and (eq TeX-master 't)      ;Test if master file itself
  2041.                 (progn                  ;But also require at least one \include
  2042.                   (save-excursion
  2043.                     (goto-char 1)       ;Too bad I have to do this search...
  2044.                     ;; Require that user uses \input{file}
  2045.                     ;; rather than            \input file
  2046.                     (re-search-forward "^[ \t]*\\\\\\(include\\|input\\){" 
  2047.                                        nil t))))
  2048.            (buffer-file-name))
  2049.           (t
  2050.            nil))))
  2051.     (cond
  2052.      ((not master)
  2053.       nil)
  2054.      ((string-match ".tex$" master)
  2055.       master)
  2056.      (t
  2057.       (concat master ".tex")))))
  2058.  
  2059. ;; I don't use this one because files are not returned in order...
  2060. ;; (defun bib-document-TeX-files ()
  2061. ;; ;; Return all tex input files associated with a known multi-file document.
  2062. ;;   (let ((master-directory (bib-master-directory))
  2063. ;;         (the-list (cons (file-name-nondirectory (TeX-master-file)) 
  2064. ;;                         (TeX-style-list)))
  2065. ;;      ;; TeX-style-list returns "../master" for the main file if TeX-master
  2066. ;;      ;; was set like that.  "../master" would not be found relative
  2067. ;;      ;; to the master-directory!  So let's add it to the list w/o directory.
  2068. ;;         (the-result)
  2069. ;;         (the-file))
  2070. ;;     (while the-list
  2071. ;;       (setq the-file (expand-file-name (car the-list) master-directory))
  2072. ;;       (setq the-list (cdr the-list))
  2073. ;;       (and (not (string-match ".tex$" the-file))
  2074. ;;            (setq the-file (concat the-file ".tex")))
  2075. ;;       (and (file-readable-p the-file)
  2076. ;;            (not (member the-file the-result)) ;listed already?
  2077. ;;            (setq the-result (cons the-file the-result))))
  2078. ;;     the-result))
  2079.  
  2080. (defun bib-document-TeX-files ()
  2081.   ;; For a multi-file document in auctex only.
  2082.   ;; Return all tex input files associated with a *known* multi-file document.
  2083.   ;; No checking is done that this is a real multi-file document.
  2084.  
  2085.   ;; sets global variable bib-document-TeX-files-warnings
  2086.   
  2087.   (setq bib-document-TeX-files-warnings nil)
  2088.   (let* ((masterfile (bib-master-file))
  2089.          (dir (and masterfile (file-name-directory masterfile)))
  2090.          (tex-buffer (get-buffer-create "*tex-document*"))
  2091.          (the-list (list masterfile))
  2092.          (the-file))
  2093.     (if (not masterfile)
  2094.         (progn
  2095.           (kill-buffer tex-buffer)
  2096.           (error 
  2097.            "Sorry, but this is not a multi-file document (Try C-u C-c C-n if using auctex)")))
  2098.     (save-excursion
  2099.       (set-buffer tex-buffer)
  2100.       ;; set its directory so relative includes work without expanding
  2101.       (setq default-directory dir)
  2102.       (insert-file-contents masterfile)
  2103.       (goto-char (point-min))
  2104.       (while (re-search-forward "^[ \t]*\\\\\\(input\\|include\\){\\(.*\\)}"
  2105.                                 nil t)
  2106.         (let ((the-file (buffer-substring (match-beginning 2)(match-end 2))))
  2107.           (if (string-match ".sty$" the-file) ;Skip over style files!
  2108.               nil
  2109.             (if (and (not (file-readable-p (expand-file-name the-file dir)))
  2110.                      (not (string-match ".tex$" the-file)))
  2111.                 (setq the-file (concat the-file ".tex")))
  2112.             (setq the-file (expand-file-name the-file dir))
  2113.             (if (not (file-readable-p the-file))
  2114.                 (setq bib-document-TeX-files-warnings
  2115.                       (concat 
  2116.                        bib-document-TeX-files-warnings
  2117.                        (format "Warning: File not found: %s" the-file)))
  2118.               (setq the-list (cons (expand-file-name the-file dir) the-list))
  2119.               (end-of-line)(insert "\n")
  2120.               (insert-file-contents the-file))))))
  2121.     (kill-buffer tex-buffer)
  2122.     (nreverse the-list)))
  2123.  
  2124. (defun bib-document-citekeys-obarray ()
  2125. ;; Return cite keys obarray for multi-file document, or nil if not a multi-file
  2126. ;; document.  This is a auc-tex supported feature only.
  2127. ;; Also, see bib-buffer-citekeys-obarray.
  2128. ;; Sets global variable bib-document-citekeys-obarray-warnings.
  2129.   (setq bib-document-citekeys-obarray-warnings nil)
  2130.   (let ((master-tex (bib-master-file))
  2131.         (master-aux))
  2132.     (if (not master-tex)
  2133.         nil                             ;Not a multifile document.  No need...
  2134.       (setq master-aux (bib-return-aux-file-from-tex master-tex "aux"))
  2135.       (or (file-readable-p master-aux)
  2136.           (error "Sorry, cannot read file %s" master-aux))
  2137.       (and (file-newer-than-file-p master-tex master-aux)
  2138.            (setq bib-document-citekeys-obarray-warnings
  2139.                  (format "Warning: %s is out of date relative to %s.\n" 
  2140.                          master-aux master-tex)))
  2141.       (let ((work-buffer (get-buffer-create "*bib-cite-work*"))
  2142.             (keys-obarray (make-vector 201 0)))
  2143.         (save-excursion
  2144.           (set-buffer work-buffer)
  2145.           (insert-file-contents master-aux)
  2146.           ;; Because we will be looking for \input statements, we need to set
  2147.           ;; the default directory to that of the master file.
  2148.           (setq default-directory (file-name-directory master-tex))
  2149.           ;; bib-make-bibliography will need this also to find .bib files
  2150.           ;; look for \@input{chap1/part1.aux}
  2151.           (while (re-search-forward "^\\\\@input{\\(.*\\)}$" nil t)
  2152.             (let* ((auxfile (buffer-substring(match-beginning 1)(match-end 1)))
  2153.                    (texfile (bib-return-aux-file-from-tex auxfile "tex")))
  2154.               (if (not (file-readable-p auxfile))
  2155.                   (setq bib-document-citekeys-obarray-warnings
  2156.                         (concat 
  2157.                          bib-document-citekeys-obarray-warnings
  2158.                          (format "Warning: %s is not found or readable.\n" 
  2159.                                  auxfile)))
  2160.                 (if (file-newer-than-file-p texfile auxfile)
  2161.                     (setq bib-document-citekeys-obarray-warnings
  2162.                           (concat 
  2163.                            bib-document-citekeys-obarray-warnings
  2164.                            (format 
  2165.                             "Warning: %s is out of date relative to %s.\n" 
  2166.                             auxfile texfile))))
  2167.                 (end-of-line)(insert "\n")
  2168.                 (insert-file-contents (buffer-substring (match-beginning 1)
  2169.                                                         (match-end 1))))))
  2170.           (goto-char 1)
  2171.  
  2172. ;;; Patched by calvanes@dis.uniroma1.it (Diego Calvanese)
  2173. ;;;      ;; look for \citation{gertsenshtein59}
  2174. ;;;       (while (re-search-forward "^\\\\citation{\\(.*\\)}$" nil t)
  2175. ;;;         (intern (buffer-substring (match-beginning 1)(match-end 1))
  2176. ;;;                 keys-obarray))
  2177.           ;; look for \citation{gertsenshtein59,vardi88,...,ullmann90}
  2178.           ;; comma-separation generated by certain LaTeX styles.
  2179.           (while (re-search-forward "^\\\\citation{\\(.*\\)}$" nil t)
  2180.         (let ((string (buffer-substring (match-beginning 1)(match-end 1)))
  2181.           (start 0))
  2182.           (while (string-match "\\([^,\n]+\\)" string start)
  2183.         (intern (substring string (match-beginning 1) (match-end 1))
  2184.             keys-obarray)
  2185.         (setq start (match-end 0))))))
  2186.         (kill-buffer work-buffer)
  2187.         keys-obarray))))
  2188.  
  2189. (defun bib-return-aux-file-from-tex (texname ext)
  2190. ;; given name.name.XXX return name.name.ext
  2191.   (concat (substring texname 0 -3) ext)) 
  2192.  
  2193. (defun bib-etags-find-noselect (tag &optional masterdir)
  2194. ;; Returns a buffer with point on `tag'.  buffer is not selected.
  2195. ;; Makes sure TAGS file exists, etc.
  2196.   (require 'etags)
  2197.   (let* ((master (or masterdir (bib-master-directory)))
  2198.          (the-buffer (current-buffer))
  2199.          (new-buffer)
  2200.          (the-tags-file-name (expand-file-name bib-etags-filename master)))
  2201.     (or (file-exists-p the-tags-file-name) ;make sure TAGS exists
  2202.         (bib-etags master))
  2203.     (or (equal the-tags-file-name tags-file-name) ;make sure it's current
  2204.         (visit-tags-table the-tags-file-name)) 
  2205.     ;; find-tag-noselect should set the TAGS file for the new buffer
  2206.     ;; that's what C-h f visit-tags-table says...
  2207.     (if (string-match "XEmacs\\|Lucid" emacs-version)
  2208.         (progn
  2209.           (find-tag tag)
  2210.           (setq new-buffer (current-buffer))
  2211.           (set-buffer the-buffer))
  2212.       (setq new-buffer (find-tag-noselect tag)) ;Seems to set buffer to TAGS
  2213.       (set-buffer the-buffer))
  2214.     new-buffer))
  2215.  
  2216. ;;---------------------------------------------------------------------------
  2217. ;; imenu stuff
  2218. ;; All of this should only be loaded if imenu is *already* loaded because
  2219. ;; we redefine imenu here.
  2220.  
  2221. (cond
  2222.  (bib-use-imenu
  2223.   (require 'imenu)
  2224.   (require 'cl)
  2225.   ;;; Now done at end of this file:
  2226.   ;;(add-hook 'LaTeX-mode-hook 'LaTeX-hook-setq-imenu)
  2227.  
  2228.   (defvar bib-imenu-document-counter nil
  2229.     "bib-cite internal variable")
  2230.  
  2231.   (defun imenu--create-LaTeX-index ()
  2232.     ;; dispatch to proper function, depending on whether a multi-file document.
  2233.     (let ((masterfile (bib-master-file)))
  2234.       (if masterfile
  2235.           (imenu--create-LaTeX-index-for-document masterfile)
  2236.         (imenu--create-LaTeX-index-for-buffer))))
  2237.  
  2238.   (defun imenu--create-LaTeX-index-for-document (masterfile)
  2239.     ;; For a multi-file document in auctex only.
  2240.     ;; Create imenu--index-alist for master file buffer and use the same
  2241.     ;; for all input files?  This would be faster...  Maybe in next version?
  2242.     ;;FIXME: How about parsing TAGS file instead of search through all files?
  2243.     (bib-etags)                         ;Create a new TAGS file, user needs it.
  2244.     (let ((tex-buffer (get-buffer-create "*imenu-tex*"))
  2245.           (index-alist '())
  2246.           (index-label-alist '())
  2247.           (prev-pos))
  2248.       (save-excursion
  2249.         (set-buffer tex-buffer)
  2250.         ;; set its directory so relative includes work without expanding
  2251.         (setq default-directory (file-name-directory masterfile))
  2252.         (insert-file-contents masterfile)
  2253.         (goto-char (point-min))
  2254.         (while (re-search-forward 
  2255.                 "^[ \t]*\\\\\\(input\\|include\\){\\([^}]*\\)}" nil t)
  2256.           (let ((the-file (buffer-substring (match-beginning 2)(match-end 2))))
  2257.             (if (and (not (file-readable-p 
  2258.                            (expand-file-name the-file default-directory)))
  2259.                      (not (string-match ".tex$" the-file)))
  2260.                 (setq the-file (concat the-file ".tex")))
  2261.             (end-of-line)(insert "\n")
  2262.             (insert-file-contents the-file)))
  2263.         ;; Now, the document is like any other tex file
  2264.         (setq bib-imenu-document-counter -99) ;IDs menu entries start at -100
  2265.         (goto-char (point-max))
  2266.         (imenu-progress-message prev-pos 0 t)
  2267.         (while 
  2268.             (re-search-backward  
  2269. ;;;          "\\\\\\(\\(sub\\)*section\\|chapter\\|label\\){[^}]+}" 
  2270.              "\\(\\(\\\\label\\)\\|\\(^[ ]*\\\\\\(\\(sub\\)*section\\|chapter\\)\\)\\){[^}]+}"
  2271.              nil t)
  2272.           (imenu-progress-message prev-pos nil t)
  2273.           (save-match-data
  2274.             (save-excursion
  2275.               (cond
  2276.                ((looking-at "\\\\label")
  2277.                 (push (imenu--LaTeX-name-and-etags)
  2278.                       index-label-alist))
  2279.                (t
  2280.                 (push (imenu--LaTeX-name-and-etags)
  2281.                     index-alist))))))
  2282.         (kill-buffer tex-buffer)
  2283.         (imenu-progress-message prev-pos 100 t)
  2284.         ;;Michal Mnuk's add-on removes \label <Michal.Mnuk@risc.uni-linz.ac.at>
  2285.         ;;Plus PSG's fix for 19.31 w/o imenu-create-submenu-name
  2286.         (and index-label-alist
  2287.              (push (cons (or (and (fboundp 'imenu-create-submenu-name)
  2288.                                   (imenu-create-submenu-name "Labels"))
  2289.                              "Labels")
  2290.                        (sort (imenu--remove-LaTeX-keyword-list 
  2291.                               index-label-alist) 'imenu--label-cmp))
  2292.                  index-alist))
  2293.         ;;(and index-label-alist
  2294.         ;;     (push (cons (imenu-create-submenu-name "Labels") 
  2295.         ;;                index-label-alist)
  2296.         ;;         index-alist))
  2297.         index-alist)))
  2298.  
  2299.   (defun imenu--create-LaTeX-index-for-buffer ()
  2300.     ;; For non-multi-file documents.
  2301.     (let ((index-alist '())
  2302.           (index-label-alist '())
  2303.           prev-pos)
  2304.       (setq bib-imenu-document-counter -99) ;IDs menu entries starting at -100
  2305.       (goto-char (point-max))
  2306.       (imenu-progress-message prev-pos 0 t)
  2307.       (while 
  2308.           (re-search-backward  
  2309. ;;; Better regexp, but slow
  2310. ;;;        "^[^;]*\\(\\\\\\)\\(\\(sub\\)*section\\|chapter\\|label\\){[^}]+}" 
  2311. ;;; Original regexp that would catch commented-out stuff
  2312. ;;;        "\\\\\\(\\(sub\\)*section\\|chapter\\|label\\){[^}]+}" 
  2313.            "\\(\\(\\\\label\\)\\|\\(^[ ]*\\\\\\(\\(sub\\)*section\\|chapter\\)\\)\\){[^}]+}"
  2314.            nil t)
  2315.         (imenu-progress-message prev-pos nil t)
  2316.         (save-match-data
  2317.           (save-excursion
  2318.             (cond
  2319.              ((looking-at "\\\\label")
  2320.               (push (imenu--LaTeX-name-and-position)
  2321.                     index-label-alist))
  2322.              (t
  2323.               (push (imenu--LaTeX-name-and-position)
  2324.                     index-alist))))))
  2325.       (imenu-progress-message prev-pos 100 t)
  2326.       ;;Michal Mnuk's add-on removes \label <Michal.Mnuk@risc.uni-linz.ac.at>
  2327.       ;;Plus PSG's fix for 19.31 w/o imenu-create-submenu-name
  2328.       (and index-label-alist
  2329.            (push (cons (or (and (fboundp 'imenu-create-submenu-name)
  2330.                                 (imenu-create-submenu-name "Labels"))
  2331.                            "Labels")
  2332.                        (sort (imenu--remove-LaTeX-keyword-list 
  2333.                               index-label-alist) 'imenu--label-cmp))
  2334.                  index-alist))
  2335.       ;;(and index-label-alist
  2336.       ;;     (push (cons (imenu-create-submenu-name "Labels") 
  2337.       ;;                index-label-alist)
  2338.       ;;         index-alist))
  2339.       index-alist))
  2340.  
  2341.   ;;Michal Mnuk's three routines:
  2342.   (defun imenu--remove-LaTeX-keyword-list (llist)
  2343.     "Remove the LaTeX KEYWORD from car's of all elements in LLIST."
  2344.     (mapcar 
  2345.      (function (lambda (element) 
  2346.                  (imenu--remove-LaTeX-keyword-el element "label"))) 
  2347.      llist))
  2348.  
  2349.   (defun imenu--remove-LaTeX-keyword-el (element keyword)
  2350.     "Remove the LaTeX KEYWORD from car of ELEMENT."
  2351.     (save-match-data
  2352.       ;; Should I have extra option here: "[
  2353.       (if (string-match (concat "\\\\" keyword "{\\(.*\\)}") (car element))
  2354.           (cons 
  2355.            (substring (car element) (match-beginning 1) (match-end 1)) 
  2356.            (cdr element)))))
  2357.   
  2358.   (defun imenu--label-cmp (el1 el2)
  2359.     "Predicate to compare labels in lists produced by 
  2360.      imenu--create-LaTeX-index."
  2361.     (string< (car el1) (car el2)))
  2362.   
  2363.   (defun imenu--LaTeX-name-and-position ()
  2364.     (save-excursion
  2365.       ;; We're on the opening slash
  2366.       (let ((beg (point))
  2367.             (end (progn (search-forward "{" nil t)
  2368.                         (forward-char -1)
  2369.                         (forward-sexp 1)
  2370.                         (point)))
  2371.             (marker (make-marker)))
  2372.         (set-marker marker beg)
  2373.         (cons (buffer-substring beg end) marker))))
  2374.  
  2375.   (defun imenu--LaTeX-name-and-etags ()
  2376.     (save-excursion
  2377.       (setq bib-imenu-document-counter (1- bib-imenu-document-counter))
  2378.       (cons (buffer-substring (point)
  2379.                               (progn (search-forward "{") 
  2380.                                      (forward-char -1)
  2381.                                      (forward-sexp 1)
  2382.                                      (point)))
  2383.             bib-imenu-document-counter)))
  2384.  
  2385.   ;; Updated to imenu in Emacs 19.33
  2386.   (defun imenu (index-item)
  2387.     "Jump to a place in the buffer chosen using a buffer menu or mouse menu.
  2388. See `imenu-choose-buffer-index' for more information."
  2389.     (interactive
  2390.      (list (save-restriction 
  2391.              (widen)
  2392.              (imenu-choose-buffer-index))))
  2393.     ;; Convert a string to an alist element.
  2394.     (if (stringp index-item)
  2395.         (setq index-item (assoc index-item (imenu--make-index-alist))))
  2396.     (and index-item
  2397.          (progn
  2398.            (push-mark)
  2399.            (cond
  2400.             ((markerp (cdr index-item))
  2401.              (if (or ( > (marker-position (cdr index-item)) (point-min))
  2402.                      ( < (marker-position (cdr index-item)) (point-max)))
  2403.                  ;; widen if outside narrowing
  2404.                  (widen))
  2405.              (goto-char (marker-position (cdr index-item))))
  2406.             ;; PSG - Handle tags
  2407.             ((and (numberp (cdr index-item))
  2408.                   (< (cdr index-item) -99))
  2409.              (find-tag (car index-item)))
  2410.             (t
  2411.              (if (or ( > (cdr index-item) (point-min))
  2412.                      ( < (cdr index-item) (point-max)))
  2413.                  ;; widen if outside narrowing
  2414.                  (widen))
  2415.              (goto-char (cdr index-item)))))))
  2416. ;;; end of bib-use-imenu stuff
  2417.   ))
  2418. ;; --------------------------------------------------------------------------
  2419. ;; The following routines make a temporary bibliography buffer 
  2420. ;; holding all bibtex files found.
  2421.  
  2422. (defun bib-get-bibliography (include-filenames-f)
  2423.   "Returns a new bibliography buffer holding all bibtex files in the document.
  2424.  
  2425. If using auc-tex, and either TeX-parse-self is set or C-c C-n is used to 
  2426. parse the document, then the entire multifile document will be searched 
  2427. for \bibliography commands.
  2428.  
  2429. If this fails, the current buffer is searched for the first \bibliography 
  2430. command.
  2431.  
  2432. If include-filenames-f is true, include as a special header the filename
  2433. of each bib file.
  2434.  
  2435. Puts the buffer in text-mode such that forward-sexp works with german \" 
  2436. accents embeded in bibtex entries."
  2437.   (let ((bib-list (or (and (fboundp 'LaTeX-bibliography-list)
  2438.                            (boundp 'TeX-auto-update)
  2439.                            (LaTeX-bibliography-list))
  2440. ;; LaTeX-bibliography-list (if bound) returns an unformatted list of
  2441. ;; bib files used in the document, but only if parsing is turned on
  2442. ;; or C-c C-n was used.
  2443.                       (bib-bibliography-list)))
  2444.         (bib-buffer (get-buffer-create "*bibtex-bibliography*"))
  2445.         ;; Path is relative to the master directory
  2446.         (default-directory (bib-master-directory))
  2447.         (the-name)(the-warnings)(the-file))
  2448.     (save-excursion                     
  2449.       ;; such that forward-sexp works with embeeded \" in german, 
  2450.       ;; and unbalanced ()
  2451.       (set-buffer bib-buffer)
  2452.       (erase-buffer)
  2453.       (set-syntax-table text-mode-syntax-table)
  2454. ;;      (if (boundp 'bibtex-mode-syntax-table)
  2455. ;;          (set-syntax-table bibtex-mode-syntax-table)
  2456. ;;        (text-mode))
  2457.       )
  2458.     ;;We have a list of bib files
  2459.     ;;Search for them, include them, list those not readable
  2460.     (while bib-list
  2461.       (setq the-name (car (car bib-list))) ;Extract the string only
  2462.       (setq bib-list (cdr bib-list))
  2463.       (setq the-name 
  2464.             (substring the-name 
  2465.                        (string-match "[^ ]+" the-name) ;remove leading spaces
  2466.                        (string-match "[ ]+$" the-name))) ;remove trailing space 
  2467.       (if (not (string-match "\\.bib$" the-name))
  2468.           (setq the-name (concat the-name ".bib")))
  2469.       (setq the-file
  2470.             (or
  2471.              (and (file-readable-p (expand-file-name (concat "./" the-name)))
  2472.                   (expand-file-name (concat "./" the-name)))
  2473.              (psg-checkfor-file-list the-name 
  2474.                                      (psg-list-env bib-bibtex-env-variable))
  2475.              ;; Check for BIBINPUT env variable as well (by popular demand!)
  2476.              (psg-checkfor-file-list the-name (psg-list-env "BIBINPUT"))
  2477.              (and (boundp 'TeX-check-path)
  2478.                   (psg-checkfor-file-list the-name TeX-check-path))))
  2479.       (if the-file
  2480.           (progn 
  2481.             (save-excursion
  2482.               (set-buffer bib-buffer)
  2483.               (goto-char (point-max))
  2484.               (if include-filenames-f
  2485.                   (insert "%%%Filename: " the-file "\n"))
  2486.               (insert-file-contents the-file nil)
  2487.               (goto-char 1)))
  2488.         (setq the-warnings 
  2489.               (concat the-warnings "Could not read file: " the-name "\n"))))
  2490.     (if the-warnings
  2491.         (progn
  2492.           (with-output-to-temp-buffer "*Help*" 
  2493.             (princ the-warnings))
  2494.           (kill-buffer bib-buffer)
  2495.           (error 
  2496.            "Sorry, can't find all bibtex files in \\bibliography command"))
  2497.       bib-buffer)))
  2498.  
  2499. (defun bib-bibliography-list ()
  2500.   "Return list of bib files listed in first \\bibliography command in buffer
  2501. Similar output to auc-tex's LaTeX-bibliography-list
  2502. The first element may contain trailing whitespace (if there was any in input)
  2503. although BiBTeX doesn't allow it!"
  2504.   (save-excursion
  2505.     (goto-char 1)
  2506.     (if (not (re-search-forward "^[ \t]*\\\\bibliography{[ \t]*\\([^},]+\\)" 
  2507.                                 nil t))
  2508.         (error "Sorry, can't find \\bibliography command anywhere")
  2509.       (let ((the-list (list (buffer-substring 
  2510.                              (match-beginning 1)(match-end 1))))
  2511.             (doNext t))
  2512.         (while doNext
  2513.           (if (looking-at ",")
  2514.               (setq the-list
  2515.                     (append the-list
  2516.                             (list (buffer-substring 
  2517.                                    (progn (skip-chars-forward ", ")(point))
  2518.                                    (progn (re-search-forward "[,}]" nil t)
  2519.                                           (backward-char 1)
  2520.                                           (skip-chars-backward ", ")
  2521.                                           (point))))))
  2522.             (setq doNext nil)))
  2523.         (mapcar 'list the-list)))))
  2524.  
  2525. ;; BibTeX-mode key def to create auc-tex's parsing file. 
  2526. (defun bib-create-auto-file ()
  2527.   "Force the creation of the auc-tex auto file for a bibtex buffer"
  2528.   (interactive)
  2529.   (if (not (require 'latex))
  2530.       (error "Sorry, This is only useful if you have auc-tex")) 
  2531.   (let ((TeX-auto-save t)
  2532.        (TeX-auto-update t)
  2533.        (TeX-auto-regexp-list BibTeX-auto-regexp-list))
  2534.     ;; TeX-auto-write   
  2535.     ;; -> calls TeX-auto-store 
  2536.     ;;    -> calls TeX-auto-parse
  2537.     ;;       clears LaTeX-auto-bibtem (temporary holding space for bibitems)
  2538.     ;;       searches buffer using regexp in TeX-auto-regexp-list
  2539.     ;;    -> if LaTeX-auto-bibtem (the temporary holding space for bibitems) 
  2540.     ;;       holds stuffs like 
  2541.     ;;         ("Zimmermann:1991" "Anger_et_al:1993")
  2542.     ;;       as determined by 
  2543.     ;;         (member nil (mapcar 'TeX-auto-entry-clear-p TeX-auto-parser))
  2544.     ;;       then it creates the auto file.
  2545.  
  2546.     ;; TeX-auto-write may call TeX-master-file which may fail if 
  2547.     ;; TeX-header-end is unset (by LaTeX-common-initialization in latex-mode)
  2548.     (if (not TeX-header-end)
  2549.         (setq TeX-header-end LaTeX-header-end))
  2550.  
  2551.     (TeX-auto-write)))
  2552.  
  2553. ;; --------------------------------------------------------------------------
  2554. ;; The following routines are also defined in other packages...
  2555.  
  2556. ;; Must be in sync with function of same name in ff-paths.el
  2557. (defun psg-checkfor-file-list (filename list)
  2558.   "Check for presence of FILENAME in directory LIST. Return 1st found path."
  2559.   ;;USAGE: (psg-checkfor-file-list "gri.cmd" (psg-list-env "PATH"))
  2560.   ;;USAGE: (psg-checkfor-file-list "gri-mode.el" load-path)
  2561.   ;;USAGE: (psg-checkfor-file-list "gri.cmd" (psg-translate-ff-list "gri.tmp"))
  2562.   (let ((the-list list) 
  2563.         (filespec))
  2564.     (while the-list
  2565.       (if (not (car the-list))          ; it is nil
  2566.           (setq filespec (expand-file-name filename "~"))
  2567.         (setq filespec 
  2568.               (concat (file-name-as-directory (car the-list)) filename)))
  2569.       (if (file-exists-p filespec)
  2570.             (setq the-list nil)
  2571.         (setq filespec nil)
  2572.         (setq the-list (cdr the-list))))
  2573.     (if filespec
  2574.         filespec
  2575.       ;; If I have not found a file yet, then check if some directories
  2576.       ;; ended in // and recurse through them.
  2577.       (let ((the-list list))
  2578.         (while the-list
  2579.           (if (not (string-match "//$" (car the-list))) nil
  2580.             (setq filespec (car 
  2581.                             (search-directory-tree 
  2582.                              (substring (car the-list) 0 (match-beginning 0)) 
  2583.                              (concat "^" filename "$") 
  2584.                              t
  2585.                              t)))
  2586.             (if filespec                ;Success!
  2587.                 (setq the-list nil)))
  2588.           (setq the-list (cdr the-list)))
  2589.         filespec))))
  2590.  
  2591.  
  2592. (defun search-directory-tree (directories extension-regexp recurse first-file)
  2593.   "Return a list of all reachable files in DIRECTORIES ending with EXTENSION.
  2594. DIRECTORIES is a list or a single-directory string
  2595. EXTENSION is actually (any) regexp, usually \\\\.bib$
  2596. If RECURSE is t, then we will recurse into the directory tree, 
  2597.               nil, we will only search the list given.
  2598. If FIRST-FILE is t, stop after first file is found."
  2599.   (or (listp directories)
  2600.       (setq directories (list directories)))
  2601.     
  2602.   (let (match)
  2603.     (while directories
  2604.       (let* ((directory (file-name-as-directory  (car directories)))
  2605.              (content (and directory
  2606.                (file-readable-p directory)
  2607.                (file-directory-p directory)
  2608.                (directory-files directory))))
  2609.         (setq directories (cdr directories))
  2610.         (while content
  2611.           (let ((file (expand-file-name (car content) directory)))
  2612.             (cond ((string-match "[.]+$" (car content))) ;This or parent dir
  2613.                   ((not (file-readable-p file)))
  2614.                   ((and recurse
  2615.                         (file-directory-p file))
  2616.                    (setq directories
  2617.                          (cons (file-name-as-directory file) directories)))
  2618.                   ((string-match extension-regexp 
  2619.                                  (file-name-nondirectory file))
  2620.                    (and first-file
  2621.                         (setq content nil
  2622.                               directories nil))
  2623.                    (setq match (cons file match)))))
  2624.           (setq content (cdr content)))))
  2625.     
  2626.     match))
  2627.  
  2628. ;;; (defun psg-checkfor-file-list (filename list)
  2629. ;;;   (let ((the-list list) 
  2630. ;;;         (filespec))
  2631. ;;;     (while the-list
  2632. ;;;       (if (not (car the-list))          ; it is nil
  2633. ;;;           (setq filespec (concat "~/" filename))
  2634. ;;;         (setq filespec 
  2635. ;;;               (concat (file-name-as-directory (car the-list)) filename)))
  2636. ;;;       (if (file-exists-p filespec)
  2637. ;;;             (setq the-list nil)
  2638. ;;;         (setq filespec nil)
  2639. ;;;         (setq the-list (cdr the-list))))
  2640. ;;;     filespec))
  2641.  
  2642. (or (fboundp 'dired-replace-in-string)
  2643.     ;; This code is part of GNU emacs
  2644.     (defun dired-replace-in-string (regexp newtext string)
  2645.       ;; Replace REGEXP with NEWTEXT everywhere in STRING and return result.
  2646.       ;; NEWTEXT is taken literally---no \\DIGIT escapes will be recognized.
  2647.       (let ((result "") (start 0) mb me)
  2648.         (while (string-match regexp string start)
  2649.           (setq mb (match-beginning 0)
  2650.                 me (match-end 0)
  2651.                 result (concat result (substring string start mb) newtext)
  2652.                 start me))
  2653.         (concat result (substring string start)))))
  2654.  
  2655.  
  2656. ;; Could use fset here to equal TeX-split-string to dired-split if only 
  2657. ;; dired-split is defined.  That would eliminate a check in psg-list-env.
  2658. (and (not (fboundp 'TeX-split-string))
  2659.      (not (fboundp 'dired-split))
  2660.      ;; This code is part of auc-tex
  2661.      (defun TeX-split-string (char string)
  2662.        "Returns a list of strings. given REGEXP the STRING is split into 
  2663. sections which in string was seperated by REGEXP.
  2664.  
  2665. Examples:
  2666.  
  2667.       (TeX-split-string \"\:\" \"abc:def:ghi\")
  2668.           -> (\"abc\" \"def\" \"ghi\")
  2669.  
  2670.       (TeX-split-string \" *\" \"dvips -Plw -p3 -c4 testfile.dvi\")
  2671.  
  2672.           -> (\"dvips\" \"-Plw\" \"-p3\" \"-c4\" \"testfile.dvi\")
  2673.  
  2674. If CHAR is nil, or \"\", an error will occur."
  2675.        
  2676.        (let ((regexp char)
  2677.              (start 0)
  2678.              (result '()))
  2679.          (while (string-match regexp string start)
  2680.            (let ((match (string-match regexp string start)))
  2681.              (setq result (cons (substring string start match) result))
  2682.              (setq start (match-end 0))))
  2683.          (setq result (cons (substring string start nil) result))
  2684.          (nreverse result))))
  2685.  
  2686. ;; Must be in sync with function of same name in ff-paths.el
  2687. ;; (See also PC-include-file-path in standard emacs ditsribution.)
  2688. (defun psg-list-env (env)
  2689.   "Return a list of directory elements in ENVIRONMENT variable (w/o leading $)
  2690. argument may consist of environment variable plus a trailing directory, e.g.
  2691. HOME or HOME/bin (trailing directory not supported in dos or OS/2).
  2692.  
  2693. bib-dos-or-os2-variable affects:
  2694.   path separator used (: or ;)
  2695.   whether backslashes are converted to slashes"
  2696.   (if (not (getenv env))
  2697.       nil                               ;Because dired-replace-in-string fails
  2698.     (let* ((value (if bib-dos-or-os2-variable
  2699.                       (dired-replace-in-string "\\\\" "/" (getenv env))
  2700.                     (getenv env)))
  2701.            (sep-char (or (and bib-dos-or-os2-variable ";") ":"))
  2702.            (entries (and value 
  2703.                          (or (and (fboundp 'TeX-split-string)
  2704.                                   (TeX-split-string sep-char value))
  2705.                              (dired-split sep-char value))))
  2706.            entry
  2707.            answers)
  2708.       (while entries
  2709.         (setq entry (car entries))
  2710.         (setq entries (cdr entries))
  2711.         (if (file-directory-p entry)
  2712.             (setq answers (cons entry answers))))
  2713.       (nreverse answers))))
  2714.  
  2715.  
  2716. (provide 'bib-cite)
  2717. ;;; bib-cite.el ends here
  2718.